Merge pull request #2469 from Esalarc/group_chat_queue_display Adding display of queued speakers in group chat windows.
Signed| @@ -68,9 +68,9 @@ | ||
| 68 | 68 | margin-top: 0.25rem; |
| 69 | 69 | margin-bottom: 0.5rem; |
| 70 | 70 | border: 1px solid var(--SmartThemeBorderColor); |
| 71 | - ; | |
| 72 | 71 | border-radius: 10px; |
| 73 | 72 | background-color: var(--black30a); |
| 73 | + padding: 2px; | |
| 74 | 74 | } |
| 75 | 75 | |
| 76 | 76 | #rm_group_buttons_expander { |
| @@ -4141,6 +4141,10 @@ | ||
| 4141 | 4141 | <input id="request_token_probabilities" type="checkbox" /> |
| 4142 | 4142 | <small data-i18n="Request token probabilities">Request token probabilities</small> |
| 4143 | 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]In group chat, highlight the character(s) that are currently queued to generate responses and the order in which they will respond."> | |
| 4145 | + <input id="show_group_chat_queue" type="checkbox" /> | |
| 4146 | + <small data-i18n="Show group chat queue">Show group chat queue</small> | |
| 4147 | + </label> | |
| 4144 | 4148 | <div data-newbie-hidden class="inline-drawer wide100p flexFlowColumn"> |
| 4145 | 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 | 4150 | <b><span data-i18n="Auto-swipe">Auto-swipe</span></b> |
| @@ -5796,6 +5800,7 @@ | ||
| 5796 | 5800 | <div class="tags tags_inline"></div> |
| 5797 | 5801 | </div> |
| 5798 | 5802 | <input class="ch_fav" value="" hidden /> |
| 5803 | + <div class="queue_position"></div> | |
| 5799 | 5804 | <div class="group_member_icon"> |
| 5800 | 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 | 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> |
| @@ -70,6 +70,7 @@ import { | ||
| 70 | 70 | animation_duration, |
| 71 | 71 | depth_prompt_role_default, |
| 72 | 72 | shouldAutoContinue, |
| 73 | + this_chid, | |
| 73 | 74 | } from '../script.js'; |
| 74 | 75 | import { printTagList, createTagMapFromList, applyTagsOnCharacterSelect, tag_map, applyTagsOnGroupSelect } from './tags.js'; |
| 75 | 76 | import { FILTER_TYPES, FilterHelper } from './filters.js'; |
| @@ -120,6 +121,8 @@ const DEFAULT_AUTO_MODE_DELAY = 5; | ||
| 120 | 121 | export const groupCandidatesFilter = new FilterHelper(debounce(printGroupCandidates, debounce_timeout.quick)); |
| 121 | 122 | let autoModeWorker = null; |
| 122 | 123 | const saveGroupDebounced = debounce(async (group, reload) => await _save(group, reload), debounce_timeout.relaxed); |
| 124 | +/** @type {Map<string, number>} */ | |
| 125 | +let groupChatQueueOrder = new Map(); | |
| 123 | 126 | |
| 124 | 127 | function setAutoModeWorker() { |
| 125 | 128 | clearInterval(autoModeWorker); |
| @@ -857,7 +860,13 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { | ||
| 857 | 860 | await saveChatConditional(); |
| 858 | 861 | $('#send_textarea').val('')[0].dispatchEvent(new Event('input', { bubbles: true })); |
| 859 | 862 | } |
| 863 | + groupChatQueueOrder = new Map(); | |
| 860 | 864 | |
| 865 | + if (power_user.show_group_chat_queue) { | |
| 866 | + for (let i = 0; i < activatedMembers.length; ++i) { | |
| 867 | + groupChatQueueOrder.set(characters[activatedMembers[i]].avatar, i + 1); | |
| 868 | + } | |
| 869 | + } | |
| 861 | 870 | // now the real generation begins: cycle through every activated character |
| 862 | 871 | for (const chId of activatedMembers) { |
| 863 | 872 | throwIfAborted(); |
| @@ -865,6 +874,9 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { | ||
| 865 | 874 | const generateType = type == 'swipe' || type == 'impersonate' || type == 'quiet' || type == 'continue' ? type : 'group_chat'; |
| 866 | 875 | setCharacterId(chId); |
| 867 | 876 | setCharacterName(characters[chId].name); |
| 877 | + if (power_user.show_group_chat_queue) { | |
| 878 | + printGroupMembers(); | |
| 879 | + } | |
| 868 | 880 | await eventSource.emit(event_types.GROUP_MEMBER_DRAFTED, chId); |
| 869 | 881 | |
| 870 | 882 | if (type !== 'swipe' && type !== 'impersonate' && !isStreamingEnabled()) { |
| @@ -885,6 +897,10 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { | ||
| 885 | 897 | messageChunk = textResult?.messageChunk; |
| 886 | 898 | } |
| 887 | 899 | } |
| 900 | + if (power_user.show_group_chat_queue) { | |
| 901 | + groupChatQueueOrder.delete(characters[chId].avatar); | |
| 902 | + groupChatQueueOrder.forEach((value, key, map) => map.set(key, value - 1)); | |
| 903 | + } | |
| 888 | 904 | } |
| 889 | 905 | } finally { |
| 890 | 906 | typingIndicator.hide(); |
| @@ -892,6 +908,10 @@ async function generateGroupWrapper(by_auto_mode, type = null, params = {}) { | ||
| 892 | 908 | is_group_generating = false; |
| 893 | 909 | setSendButtonState(false); |
| 894 | 910 | setCharacterId(undefined); |
| 911 | + if (power_user.show_group_chat_queue) { | |
| 912 | + groupChatQueueOrder = new Map(); | |
| 913 | + printGroupMembers(); | |
| 914 | + } | |
| 895 | 915 | setCharacterName(''); |
| 896 | 916 | activateSendButtons(); |
| 897 | 917 | showSwipeButtons(); |
| @@ -1318,6 +1338,14 @@ function getGroupCharacterBlock(character) { | ||
| 1318 | 1338 | template.attr('chid', characters.indexOf(character)); |
| 1319 | 1339 | template.find('.ch_fav').val(isFav); |
| 1320 | 1340 | template.toggleClass('is_fav', isFav); |
| 1341 | + | |
| 1342 | + let queuePosition = groupChatQueueOrder.get(character.avatar); | |
| 1343 | + if (queuePosition) { | |
| 1344 | + template.find('.queue_position').text(queuePosition); | |
| 1345 | + template.toggleClass('is_queued', queuePosition > 1); | |
| 1346 | + template.toggleClass('is_active', queuePosition === 1); | |
| 1347 | + } | |
| 1348 | + | |
| 1321 | 1349 | template.toggleClass('disabled', isGroupMemberDisabled(character.avatar)); |
| 1322 | 1350 | |
| 1323 | 1351 | // Display inline tags |
| @@ -1610,6 +1638,7 @@ export async function openGroupById(groupId) { | ||
| 1610 | 1638 | select_group_chats(groupId); |
| 1611 | 1639 | |
| 1612 | 1640 | if (selected_group !== groupId) { |
| 1641 | + groupChatQueueOrder = new Map(); | |
| 1613 | 1642 | await clearChat(); |
| 1614 | 1643 | cancelTtsPlay(); |
| 1615 | 1644 | selected_group = groupId; |
| @@ -179,6 +179,7 @@ let power_user = { | ||
| 179 | 179 | send_on_enter: send_on_enter_options.AUTO, |
| 180 | 180 | console_log_prompts: false, |
| 181 | 181 | request_token_probabilities: false, |
| 182 | + show_group_chat_queue: false, | |
| 182 | 183 | render_formulas: false, |
| 183 | 184 | allow_name1_display: false, |
| 184 | 185 | allow_name2_display: false, |
| @@ -1601,6 +1602,7 @@ function loadPowerUserSettings(settings, data) { | ||
| 1601 | 1602 | |
| 1602 | 1603 | $('#console_log_prompts').prop('checked', power_user.console_log_prompts); |
| 1603 | 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 | 1606 | $('#auto_fix_generated_markdown').prop('checked', power_user.auto_fix_generated_markdown); |
| 1605 | 1607 | $('#auto_scroll_chat_to_bottom').prop('checked', power_user.auto_scroll_chat_to_bottom); |
| 1606 | 1608 | $('#bogus_folders').prop('checked', power_user.bogus_folders); |
| @@ -3567,6 +3569,11 @@ $(document).ready(() => { | ||
| 3567 | 3569 | saveSettingsDebounced(); |
| 3568 | 3570 | }); |
| 3569 | 3571 | |
| 3572 | + $('#show_group_chat_queue').on('input', function () { | |
| 3573 | + power_user.show_group_chat_queue = !!$(this).prop('checked'); | |
| 3574 | + saveSettingsDebounced(); | |
| 3575 | + }); | |
| 3576 | + | |
| 3570 | 3577 | $('#auto_scroll_chat_to_bottom').on('input', function () { |
| 3571 | 3578 | power_user.auto_scroll_chat_to_bottom = !!$(this).prop('checked'); |
| 3572 | 3579 | saveSettingsDebounced(); |
| @@ -2922,6 +2922,23 @@ input[type=search]:focus::-webkit-search-cancel-button { | ||
| 2922 | 2922 | position: relative; |
| 2923 | 2923 | } |
| 2924 | 2924 | |
| 2925 | +.group_member .queue_position:not(:empty)::before { | |
| 2926 | + content: "#"; | |
| 2927 | +} | |
| 2928 | + | |
| 2929 | +.group_member .queue_position { | |
| 2930 | + margin-right: 0.75rem; | |
| 2931 | + font-size: calc(var(--mainFontSize) * 0.9); | |
| 2932 | +} | |
| 2933 | + | |
| 2934 | +.group_member.is_queued { | |
| 2935 | + outline: 2px solid var(--golden); | |
| 2936 | +} | |
| 2937 | + | |
| 2938 | +.group_member.is_active { | |
| 2939 | + outline: 2px solid var(--active); | |
| 2940 | +} | |
| 2941 | + | |
| 2925 | 2942 | .character_select.is_fav .avatar, |
| 2926 | 2943 | .group_select.is_fav .avatar, |
| 2927 | 2944 | .group_member.is_fav .avatar, |