Group Chat Queue Display - removing queue position from character object - storing in map in group_chat.js instead - moving queue position to div - moving '#' from js to css ::before - adding option to settings - cleaning up guards

2fccd83083b714e165eda5102112b7b21ba4865c

David Fedolfi <dfedolfi@gmail.com>

4 files changed, +39 -16Ignore whitespace
public/index.html+5 -0
@@ -4141,6 +4141,10 @@
4141 <input id="request_token_probabilities" type="checkbox" />4141 <input id="request_token_probabilities" type="checkbox" />
4142 <small data-i18n="Request token probabilities">Request token probabilities</small>4142 <small data-i18n="Request token probabilities">Request token probabilities</small>
4143 </label>4143 </label>
4144 <label data-newbie-hidden class="checkbox_label" for="show_group_chat_queue" title="In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond." data-i18n="[title]Requests logprobs from the API for the Token Probabilities feature">
4145 <input id="show_group_chat_queue" type="checkbox" />
4146 <small data-i18n="Request token probabilities">Show group chat queue</small>
4147 </label>
4144 <div data-newbie-hidden class="inline-drawer wide100p flexFlowColumn">4148 <div data-newbie-hidden class="inline-drawer wide100p flexFlowColumn">
4145 <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria">4149 <div class="inline-drawer-toggle inline-drawer-header userSettingsInnerExpandable" title="Automatically reject and re-generate AI message based on configurable criteria." data-i18n="[title]Automatically reject and re-generate AI message based on configurable criteria">
4146 <b><span data-i18n="Auto-swipe">Auto-swipe</span></b>4150 <b><span data-i18n="Auto-swipe">Auto-swipe</span></b>
@@ -5796,6 +5800,7 @@
5796 <div class="tags tags_inline"></div>5800 <div class="tags tags_inline"></div>
5797 </div>5801 </div>
5798 <input class="ch_fav" value="" hidden />5802 <input class="ch_fav" value="" hidden />
5803 <div class="queue_position"></div>
5799 <div class="group_member_icon">5804 <div class="group_member_icon">
5800 <div title="Temporarily disable automatic replies from this character" data-action="disable" class="right_menu_button fa-solid fa-lg fa-comment-slash" data-i18n="[title]Temporarily disable automatic replies from this character"></div>5805 <div title="Temporarily disable automatic replies from this character" data-action="disable" class="right_menu_button fa-solid fa-lg fa-comment-slash" data-i18n="[title]Temporarily disable automatic replies from this character"></div>
5801 <div title="Enable automatic replies from this character" data-action="enable" class="right_menu_button fa-solid fa-lg fa-comment-slash" data-i18n="[title]Enable automatic replies from this character"></div>5806 <div title="Enable automatic replies from this character" data-action="enable" class="right_menu_button fa-solid fa-lg fa-comment-slash" data-i18n="[title]Enable automatic replies from this character"></div>
public/scripts/group-chats.js+19 -16
@@ -121,6 +121,7 @@ const DEFAULT_AUTO_MODE_DELAY = 5;
121export const groupCandidatesFilter = new FilterHelper(debounce(printGroupCandidates, debounce_timeout.quick));121export const groupCandidatesFilter = new FilterHelper(debounce(printGroupCandidates, debounce_timeout.quick));
122let autoModeWorker = null;122let autoModeWorker = null;
123const saveGroupDebounced = debounce(async (group, reload) => await _save(group, reload), debounce_timeout.relaxed);123const saveGroupDebounced = debounce(async (group, reload) => await _save(group, reload), debounce_timeout.relaxed);
124let groupChatQueueOrder = new Map();
124125
125function setAutoModeWorker() {126function setAutoModeWorker() {
126 clearInterval(autoModeWorker);127 clearInterval(autoModeWorker);
@@ -787,7 +788,6 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
787 return Promise.resolve();788 return Promise.resolve();
788 }789 }
789 790
790 const showChatQueue = (!(typingIndicator.length === 0 && !isStreamingEnabled()) && openGroupId);
791 try {791 try {
792 throwIfAborted();792 throwIfAborted();
793 hideSwipeButtons();793 hideSwipeButtons();
@@ -859,9 +859,11 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
859 await saveChatConditional();859 await saveChatConditional();
860 $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles:true }));860 $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles:true }));
861 }861 }
862 if (showChatQueue){862 groupChatQueueOrder = new Map();
863
864 if (power_user.show_group_chat_queue){
863 for (let i = 0; i < activatedMembers.length; ++i){865 for (let i = 0; i < activatedMembers.length; ++i){
864 characters[activatedMembers[i]].queueOrder = (i+1);866 groupChatQueueOrder.set(characters[activatedMembers[i]].avatar, i+1);
865 }867 }
866 }868 }
867 // now the real generation begins: cycle through every activated character869 // now the real generation begins: cycle through every activated character
@@ -871,7 +873,7 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
871 const generateType = type == 'swipe' || type == 'impersonate' || type == 'quiet' || type == 'continue' ? type : 'group_chat';873 const generateType = type == 'swipe' || type == 'impersonate' || type == 'quiet' || type == 'continue' ? type : 'group_chat';
872 setCharacterId(chId);874 setCharacterId(chId);
873 setCharacterName(characters[chId].name);875 setCharacterName(characters[chId].name);
874 if (showChatQueue){876 if (power_user.show_group_chat_queue){
875 printGroupMembers();877 printGroupMembers();
876 }878 }
877 await eventSource.emit(event_types.GROUP_MEMBER_DRAFTED, chId);879 await eventSource.emit(event_types.GROUP_MEMBER_DRAFTED, chId);
@@ -894,9 +896,9 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
894 messageChunk = textResult?.messageChunk;896 messageChunk = textResult?.messageChunk;
895 }897 }
896 }898 }
897 if (showChatQueue){899 if (power_user.show_group_chat_queue){
898 activatedMembers.filter(chidx => characters[chidx].queueOrder > 0)900 groupChatQueueOrder.delete(characters[chId].avatar);
899 .forEach(chindex => characters[chindex].queueOrder -= 1);901 groupChatQueueOrder.forEach((value, key, map) => map.set(key, value-1));
900 }902 }
901 }903 }
902 } finally {904 } finally {
@@ -905,12 +907,8 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) {
905 is_group_generating = false;907 is_group_generating = false;
906 setSendButtonState(false);908 setSendButtonState(false);
907 setCharacterId(undefined);909 setCharacterId(undefined);
908 910 if (power_user.show_group_chat_queue){
909 if (showChatQueue){911 groupChatQueueOrder = new Map();
910 group.members.forEach(avatar => {
911 let character = characters.find(x => x.avatar === avatar || x.name === avatar);
912 character.queueOrder = undefined;
913 });
914 printGroupMembers();912 printGroupMembers();
915 }913 }
916 setCharacterName('');914 setCharacterName('');
@@ -1333,10 +1331,15 @@ function getGroupCharacterBlock(character) {
1333 template.find('.ch_name').text(character.name + (character.queueOrder > 0?' (#' + character.queueOrder + ')':'')); template.attr('chid', characters.indexOf(character));1331 template.find('.ch_name').text(character.name + (character.queueOrder > 0?' (#' + character.queueOrder + ')':'')); template.attr('chid', characters.indexOf(character));
1334 template.find('.ch_fav').val(isFav);1332 template.find('.ch_fav').val(isFav);
1335 template.toggleClass('is_fav', isFav);1333 template.toggleClass('is_fav', isFav);
1336 template.toggleClass('is_active', character.queueOrder === 1);1334
1337 template.toggleClass('is_queued', character.queueOrder > 1);1335 let queuePosition = groupChatQueueOrder.get(character.avatar);
1336 if (queuePosition){
1337 template.find('.queue_position').text(queuePosition);
1338 template.toggleClass('is_queued', queuePosition > 1);
1339 template.toggleClass('is_active', queuePosition === 1);
1340 }
1341
1338 template.toggleClass('disabled', isGroupMemberDisabled(character.avatar));1342 template.toggleClass('disabled', isGroupMemberDisabled(character.avatar));
1339 template.toggleClass('is_active', character.avatar === (this_chid && characters[this_chid] && characters[this_chid].avatar));
13401343
1341 // Display inline tags1344 // Display inline tags
1342 const tagsElement = template.find('.tags');1345 const tagsElement = template.find('.tags');
public/scripts/power-user.js+7 -0
@@ -179,6 +179,7 @@ let power_user = {
179 send_on_enter: send_on_enter_options.AUTO,179 send_on_enter: send_on_enter_options.AUTO,
180 console_log_prompts: false,180 console_log_prompts: false,
181 request_token_probabilities: false,181 request_token_probabilities: false,
182 show_group_chat_queue: false,
182 render_formulas: false,183 render_formulas: false,
183 allow_name1_display: false,184 allow_name1_display: false,
184 allow_name2_display: false,185 allow_name2_display: false,
@@ -1601,6 +1602,7 @@ function loadPowerUserSettings(settings, data) {
16011602
1602 $('#console_log_prompts').prop('checked', power_user.console_log_prompts);1603 $('#console_log_prompts').prop('checked', power_user.console_log_prompts);
1603 $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities);1604 $('#request_token_probabilities').prop('checked', power_user.request_token_probabilities);
1605 $('#show_group_chat_queue').prop('checked', power_user.show_group_chat_queue);
1604 $('#auto_fix_generated_markdown').prop('checked', power_user.auto_fix_generated_markdown);1606 $('#auto_fix_generated_markdown').prop('checked', power_user.auto_fix_generated_markdown);
1605 $('#auto_scroll_chat_to_bottom').prop('checked', power_user.auto_scroll_chat_to_bottom);1607 $('#auto_scroll_chat_to_bottom').prop('checked', power_user.auto_scroll_chat_to_bottom);
1606 $('#bogus_folders').prop('checked', power_user.bogus_folders);1608 $('#bogus_folders').prop('checked', power_user.bogus_folders);
@@ -3567,6 +3569,11 @@ $(document).ready(() => {
3567 saveSettingsDebounced();3569 saveSettingsDebounced();
3568 });3570 });
35693571
3572 $('#show_group_chat_queue').on('input', function () {
3573 power_user.show_group_chat_queue = !!$(this).prop('checked');
3574 saveSettingsDebounced();
3575 });
3576
3570 $('#auto_scroll_chat_to_bottom').on('input', function () {3577 $('#auto_scroll_chat_to_bottom').on('input', function () {
3571 power_user.auto_scroll_chat_to_bottom = !!$(this).prop('checked');3578 power_user.auto_scroll_chat_to_bottom = !!$(this).prop('checked');
3572 saveSettingsDebounced();3579 saveSettingsDebounced();
public/style.css+8 -0
@@ -2922,6 +2922,14 @@ input[type=search]:focus::-webkit-search-cancel-button {
2922 position: relative;2922 position: relative;
2923}2923}
29242924
2925.group_member .queue_position:not(:empty)::before {
2926 content: "#";
2927}
2928
2929.group_member .queue_position{
2930 margin-right: 1rem;
2931}
2932
2925.group_member.is_queued {2933.group_member.is_queued {
2926 border: 2px solid var(--golden);2934 border: 2px solid var(--golden);
2927}2935}