Chat lorebook click unify (#5246) * Unify chat lorebook button click behavior with character lorebook button * Update locale strings for chat lorebook button * Unify chat lorebook button click behavior with character lorebook button * Update locale strings for chat lorebook button * Also unify character lorebook button to support Alt modifier * Update locale strings for character lorebook button * Update public/locales/fr-fr.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add long-press support for lorebook buttons on mobile * Update locale strings for lorebook button long-press * Fix long-press to use event delegation for dynamic elements --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed| @@ -5832,12 +5832,18 @@ | |||
| 5832 | <div class="persona_controls_buttons_block buttons_block"> | 5832 | <div class="persona_controls_buttons_block buttons_block"> |
| 5833 | <div id="persona_rename_button" class="menu_button fa-solid fa-pencil" title="Rename Persona" data-i18n="[title]Rename Persona"></div> | 5833 | <div id="persona_rename_button" class="menu_button fa-solid fa-pencil" title="Rename Persona" data-i18n="[title]Rename Persona"></div> |
| 5834 | <div id="sync_name_button" class="menu_button fa-solid fa-sync" title="Click to set user name for all messages" data-i18n="[title]Click to set user name for all messages"></div> | 5834 | <div id="sync_name_button" class="menu_button fa-solid fa-sync" title="Click to set user name for all messages" data-i18n="[title]Click to set user name for all messages"></div> |
| 5835 | <div id="persona_lore_button" class="menu_button fa-solid fa-globe" title="Persona Lore Alt+Click to open the lorebook" data-i18n="[title]Persona Lore Alt+Click to open the lorebook"></div> | 5835 | <div id="persona_lore_button" class="menu_button fa-solid fa-globe" title="Persona Lore Click to load Shift/Alt-click or long-press to open 'Link to Persona Lorebook' popup" data-i18n="[title]persona_lore_button_title"></div> |
| 5836 | 5836 | ||
| 5837 | <div id="persona_set_image_button" class="menu_button fa-solid fa-image" title="Change Persona Image" data-i18n="[title]Change Persona Image"></div> | 5837 | <div id="persona_set_image_button" class="menu_button fa-solid fa-image" title="Change Persona Image" data-i18n="[title]Change Persona Image"></div> |
| 5838 | <div id="persona_duplicate_button" class="menu_button fa-solid fa-clone" title="Duplicate Persona" data-i18n="[title]Duplicate Persona"></div> | 5838 | <div id="persona_duplicate_button" class="menu_button fa-solid fa-clone" title="Duplicate Persona" data-i18n="[title]Duplicate Persona"></div> |
| 5839 | <div id="persona_delete_button" class="menu_button fa-solid fa-skull red_button" title="Delete Persona" data-i18n="[title]Delete Persona"></div> | 5839 | <div id="persona_delete_button" class="menu_button fa-solid fa-skull red_button" title="Delete Persona" data-i18n="[title]Delete Persona"></div> |
| 5840 | </div> | 5840 | </div> |
| 5841 | <label class="flex1 height100p" for="persona-management-dropdown"> | ||
| 5842 | <select id="persona-management-dropdown" class="text_pole"> | ||
| 5843 | <option value="default" disabled selected data-i18n="More...">More...</option> | ||
| 5844 | <option id="persona_lorebook_link" data-i18n="Link to Persona Lorebook">Link to Persona Lorebook</option> | ||
| 5845 | </select> | ||
| 5846 | </label> | ||
| 5841 | </div> | 5847 | </div> |
| 5842 | 5848 | ||
| 5843 | <h4 class="flex-container alignItemsBaseline"> | 5849 | <h4 class="flex-container alignItemsBaseline"> |
| @@ -6003,8 +6009,8 @@ | |||
| 6003 | <div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> | 6009 | <div id="favorite_button" class="menu_button fa-solid fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> |
| 6004 | <input type="hidden" id="fav_checkbox" name="fav" /> | 6010 | <input type="hidden" id="fav_checkbox" name="fav" /> |
| 6005 | <div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions" data-i18n="[title]Advanced Definition"></div> | 6011 | <div id="advanced_div" class="menu_button fa-solid fa-book " title="Advanced Definitions" data-i18n="[title]Advanced Definition"></div> |
| 6006 | <div id="world_button" class="menu_button fa-solid fa-globe" title="Character Lore Click to load Shift-click to open 'Link to World Info' popup" data-i18n="[title]world_button_title"></div> | 6012 | <div id="world_button" class="menu_button fa-solid fa-globe" title="Character Lore Click to load Shift/Alt-click or long-press to open 'Link to World Info' popup" data-i18n="[title]world_button_title"></div> |
| 6007 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Alt+Click to open the lorebook" data-i18n="[title]Chat Lore Alt+Click to open the lorebook"></div> | 6013 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Click to load Shift/Alt-click or long-press to open 'Link to Chat Lorebook' popup" data-i18n="[title]chat_lorebook_button_title"></div> |
| 6008 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> | 6014 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> |
| 6009 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> | 6015 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> |
| 6010 | <!-- <div id="set_chat_character_settings" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> | 6016 | <!-- <div id="set_chat_character_settings" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> |
| @@ -6155,8 +6161,14 @@ | |||
| 6155 | <div id="group-metadata-controls" class="marginTopBot5"> | 6161 | <div id="group-metadata-controls" class="marginTopBot5"> |
| 6156 | <div class="flex-container wide100p"> | 6162 | <div class="flex-container wide100p"> |
| 6157 | <input id="rm_group_chat_name" class="text_pole flex1" type="text" name="chat_name" data-i18n="[placeholder]Chat Name (Optional)" placeholder="Chat Name (Optional)" /> | 6163 | <input id="rm_group_chat_name" class="text_pole flex1" type="text" name="chat_name" data-i18n="[placeholder]Chat Name (Optional)" placeholder="Chat Name (Optional)" /> |
| 6158 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore" data-i18n="[title]Chat Lore"></div> | 6164 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Click to load Shift/Alt-click or long-press to open 'Link to Chat Lorebook' popup" data-i18n="[title]chat_lorebook_button_title"></div> |
| 6159 | </div> | 6165 | </div> |
| 6166 | <label class="flex1 height100p" for="group-chat-lorebook-dropdown"> | ||
| 6167 | <select id="group-chat-lorebook-dropdown" class="text_pole"> | ||
| 6168 | <option value="default" disabled selected data-i18n="More...">More...</option> | ||
| 6169 | <option id="group_chat_lorebook_link" data-i18n="Link to Chat Lorebook">Link to Chat Lorebook</option> | ||
| 6170 | </select> | ||
| 6171 | </label> | ||
| 6160 | <div id="group_tags_div" class="wide100p"> | 6172 | <div id="group_tags_div" class="wide100p"> |
| 6161 | <div class="tag_controls"> | 6173 | <div class="tag_controls"> |
| 6162 | <input id="groupTagInput" class="text_pole textarea_compact tag_input flex1 margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> | 6174 | <input id="groupTagInput" class="text_pole textarea_compact tag_input flex1 margin0" data-i18n="[placeholder]Search / Create Tags" placeholder="Search / Create tags" /> |
| @@ -1518,10 +1518,10 @@ | |||
| 1518 | "Contain": "Contenir", | 1518 | "Contain": "Contenir", |
| 1519 | "Stretch": "Étirer", | 1519 | "Stretch": "Étirer", |
| 1520 | "Center": "Centrer", | 1520 | "Center": "Centrer", |
| 1521 | "Persona Lore Alt+Click to open the lorebook": "Lore de persona\nAlt+Click pour ouvrir le lorebook", | 1521 | "persona_lore_button_title": "Lore de persona\n\nCliquer pour charger\nMajuscule/Alt-clic ou appui long pour ouvrir la fenêtre contextuelle « Lien vers le Lorebook de persona ».", |
| 1522 | "None (disabled)": "Aucun (désactivé)", | 1522 | "None (disabled)": "Aucun (désactivé)", |
| 1523 | "world_button_title": "Lore de personnage\n\nCliquer pour charger\nMajuscule-clic pour ouvrir la fenêtre contextuelle « Lien vers le Wold Info ».", | 1523 | "world_button_title": "Lore de personnage\n\nCliquer pour charger\nMajuscule/Alt-clic ou appui long pour ouvrir la fenêtre contextuelle « Lien vers le World Info ».", |
| 1524 | "Chat Lore Alt+Click to open the lorebook": "Lore du chat\nAlt+Click pour ouvrir le lorebook", | 1524 | "chat_lorebook_button_title": "Lore du chat\n\nCliquer pour charger\nMajuscule/Alt-clic ou appui long pour ouvrir la fenêtre contextuelle « Lien vers le Lorebook du chat ».", |
| 1525 | "Manual": "Manuel", | 1525 | "Manual": "Manuel", |
| 1526 | "Duplicate persona": "Dupliquer la persona", | 1526 | "Duplicate persona": "Dupliquer la persona", |
| 1527 | "popup-button-crop": "Recadrer", | 1527 | "popup-button-crop": "Recadrer", |
| @@ -1535,7 +1535,7 @@ | |||
| 1535 | "Only apply color as accent": "색상은 오직 강조로써만 적용됩니다", | 1535 | "Only apply color as accent": "색상은 오직 강조로써만 적용됩니다", |
| 1536 | "qr--colorClear": "색상 지우기", | 1536 | "qr--colorClear": "색상 지우기", |
| 1537 | "Color": "색상", | 1537 | "Color": "색상", |
| 1538 | "world_button_title": "캐릭터 로어. 클릭하여 로드하세요. Shift를 클릭하면 '월드 인포 링크' 팝업이 열립니다.", | 1538 | "world_button_title": "캐릭터 로어. 클릭하여 로드하세요. Shift/Alt+클릭 또는 길게 누르면 '월드 인포 링크' 팝업이 열립니다.", |
| 1539 | "Select TTS Provider": "TTS 공급자 선택", | 1539 | "Select TTS Provider": "TTS 공급자 선택", |
| 1540 | "tts_enabled": "활성화", | 1540 | "tts_enabled": "활성화", |
| 1541 | "Narrate user messages": "사용자 메시지 나레이션", | 1541 | "Narrate user messages": "사용자 메시지 나레이션", |
| @@ -1904,7 +1904,7 @@ | |||
| 1904 | "Save": "Сохранить", | 1904 | "Save": "Сохранить", |
| 1905 | "Chat Lorebook": "Лорбук для чата", | 1905 | "Chat Lorebook": "Лорбук для чата", |
| 1906 | "chat_world_template_txt": "Выбранный мир будет привязан к этому чату. Будет работать наряду с глобальным лорбуком и лором персонажа.", | 1906 | "chat_world_template_txt": "Выбранный мир будет привязан к этому чату. Будет работать наряду с глобальным лорбуком и лором персонажа.", |
| 1907 | "world_button_title": "Лор персонажа\n\nНажмите, чтобы загрузить\nShift + ЛКМ, чтобы открыть диалог привязки мира", | 1907 | "world_button_title": "Лор персонажа\n\nНажмите, чтобы загрузить\nShift / Alt + ЛКМ или долгое нажатие, чтобы открыть диалог привязки мира", |
| 1908 | "No auxillary Lorebooks set. Click here to select.": "Вспомогательный лорбук не выбран. Нажмите, чтобы выбрать.", | 1908 | "No auxillary Lorebooks set. Click here to select.": "Вспомогательный лорбук не выбран. Нажмите, чтобы выбрать.", |
| 1909 | "ext_regex_user_input_desc": "Отправленные вами сообщения.", | 1909 | "ext_regex_user_input_desc": "Отправленные вами сообщения.", |
| 1910 | "ext_regex_ai_input_desc": "Полученные от API ответы.", | 1910 | "ext_regex_ai_input_desc": "Полученные от API ответы.", |
| @@ -2130,7 +2130,7 @@ | |||
| 2130 | "openai_reasoning_effort_low": "Поверхностные", | 2130 | "openai_reasoning_effort_low": "Поверхностные", |
| 2131 | "openai_reasoning_effort_medium": "Обычные", | 2131 | "openai_reasoning_effort_medium": "Обычные", |
| 2132 | "openai_reasoning_effort_high": "Подробные", | 2132 | "openai_reasoning_effort_high": "Подробные", |
| 2133 | "Persona Lore Alt+Click to open the lorebook": "Лорбук данной персоны\nAlt + ЛКМ чтобы открыть лорбук", | 2133 | "persona_lore_button_title": "Лорбук данной персоны\n\nНажмите, чтобы открыть\nShift / Alt + ЛКМ или долгое нажатие, чтобы открыть диалог привязки лорбука", |
| 2134 | "Persona Lorebook for": "Лорбук для персоны", | 2134 | "Persona Lorebook for": "Лорбук для персоны", |
| 2135 | "persona_world_template_txt": "Выбранный мир будет привязан к этой персоне. Будет работать вместе с глобальным лорбуком и лорбуками персонажа и чата.", | 2135 | "persona_world_template_txt": "Выбранный мир будет привязан к этой персоне. Будет работать вместе с глобальным лорбуком и лорбуками персонажа и чата.", |
| 2136 | "Global list": "Глобальный список", | 2136 | "Global list": "Глобальный список", |
| @@ -2145,7 +2145,7 @@ | |||
| 2145 | "Enter a valid API URL": "Введите корректный адрес API", | 2145 | "Enter a valid API URL": "Введите корректный адрес API", |
| 2146 | "No Ollama model selected.": "Не выбрана модель Ollama", | 2146 | "No Ollama model selected.": "Не выбрана модель Ollama", |
| 2147 | "Background Fitting": "Способ подгонки фона под разрешение", | 2147 | "Background Fitting": "Способ подгонки фона под разрешение", |
| 2148 | "Chat Lore Alt+Click to open the lorebook": "Лорбук данного чата\nAlt + ЛКМ чтобы открыть лорбук", | 2148 | "chat_lorebook_button_title": "Лорбук данного чата\n\nНажмите, чтобы открыть\nShift / Alt + ЛКМ или долгое нажатие, чтобы открыть диалог привязки лорбука", |
| 2149 | "Token Counter": "Подсчитать токены", | 2149 | "Token Counter": "Подсчитать токены", |
| 2150 | "Type / paste in the box below to see the number of tokens in the text.": "Введите или вставьте текст в окошко ниже, чтобы подсчитать количество токенов в нём.", | 2150 | "Type / paste in the box below to see the number of tokens in the text.": "Введите или вставьте текст в окошко ниже, чтобы подсчитать количество токенов в нём.", |
| 2151 | "Selected tokenizer:": "Выбранный токенайзер:", | 2151 | "Selected tokenizer:": "Выбранный токенайзер:", |
| @@ -1053,7 +1053,7 @@ | |||
| 1053 | "Current Persona": "当前人设", | 1053 | "Current Persona": "当前人设", |
| 1054 | "Rename Persona": "重命名人设", | 1054 | "Rename Persona": "重命名人设", |
| 1055 | "Click to set user name for all messages": "点击为所有消息设置用户名", | 1055 | "Click to set user name for all messages": "点击为所有消息设置用户名", |
| 1056 | "Persona Lore Alt+Click to open the lorebook": "人设世界书\nAlt+单击 打开世界书", | 1056 | "persona_lore_button_title": "人设世界书\n\n单击加载\nShift/Alt+单击或长按打开“链接到人设世界书”弹出窗口", |
| 1057 | "Change Persona Image": "更改人设图", | 1057 | "Change Persona Image": "更改人设图", |
| 1058 | "Duplicate Persona": "复制人设", | 1058 | "Duplicate Persona": "复制人设", |
| 1059 | "Delete Persona": "删除人设", | 1059 | "Delete Persona": "删除人设", |
| @@ -1093,8 +1093,8 @@ | |||
| 1093 | "Click to select a new avatar for this character": "单击以为此角色选择新的头像", | 1093 | "Click to select a new avatar for this character": "单击以为此角色选择新的头像", |
| 1094 | "Add to Favorites": "添加到收藏夹", | 1094 | "Add to Favorites": "添加到收藏夹", |
| 1095 | "Advanced Definition": "高级定义", | 1095 | "Advanced Definition": "高级定义", |
| 1096 | "world_button_title": "角色世界书\n\n单击加载\nShift+单击打开“链接到世界书”弹出窗口", | 1096 | "world_button_title": "角色世界书\n\n单击加载\nShift/Alt+单击或长按打开“链接到世界书”弹出窗口", |
| 1097 | "Chat Lore Alt+Click to open the lorebook": "聊天世界书\nAlt+单击打开世界书", | 1097 | "chat_lorebook_button_title": "聊天世界书\n\n单击加载\nShift/Alt+单击或长按打开“链接到聊天世界书”弹出窗口", |
| 1098 | "Connected Personas": "绑定的用户设定", | 1098 | "Connected Personas": "绑定的用户设定", |
| 1099 | "Export and Download": "导出并下载", | 1099 | "Export and Download": "导出并下载", |
| 1100 | "Duplicate Character": "复制角色", | 1100 | "Duplicate Character": "复制角色", |
| @@ -1543,7 +1543,7 @@ | |||
| 1543 | "When enabled, nodes that have swipes splitting off of them will appear subtly larger, in addition to having the double border.": "啟用後,具分支滑動的節點將顯示雙重邊框,還會略微放大。", | 1543 | "When enabled, nodes that have swipes splitting off of them will appear subtly larger, in addition to having the double border.": "啟用後,具分支滑動的節點將顯示雙重邊框,還會略微放大。", |
| 1544 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized": "世界資訊條目狀態:\\r🔵 恆定\\r🟢 正常\\r🔗 向量化", | 1544 | "WI Entry Status:🔵 Constant🟢 Normal🔗 Vectorized": "世界資訊條目狀態:\\r🔵 恆定\\r🟢 正常\\r🔗 向量化", |
| 1545 | "Width of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時,節點的像素寬度。", | 1545 | "Width of a node, in pixels at zoom level 1.0.": "縮放等級為 1.0 時,節點的像素寬度。", |
| 1546 | "world_button_title": "角色背景設定\n「Shift+點選」可開啟「連結至世界資訊」彈窗", | 1546 | "world_button_title": "角色背景設定\n「Shift/Alt+點選」或長按可開啟「連結至世界資訊」彈窗", |
| 1547 | "# of Beams": "# of Beams", | 1547 | "# of Beams": "# of Beams", |
| 1548 | "Additional Parameters": "其他參數", | 1548 | "Additional Parameters": "其他參數", |
| 1549 | "All": "全部", | 1549 | "All": "全部", |
| @@ -2367,8 +2367,8 @@ | |||
| 2367 | "Contain": "自適應", | 2367 | "Contain": "自適應", |
| 2368 | "Stretch": "拉伸", | 2368 | "Stretch": "拉伸", |
| 2369 | "Center": "置中", | 2369 | "Center": "置中", |
| 2370 | "Persona Lore Alt+Click to open the lorebook": "「Alt+點選」可開啟角色知識書", | 2370 | "persona_lore_button_title": "人設知識書\n\n點選以載入\nShift/Alt+點選或長按開啟「連結人設知識書」彈窗", |
| 2371 | "Chat Lore Alt+Click to open the lorebook": "「Alt+點選」可開啟聊天知識書", | 2371 | "chat_lorebook_button_title": "聊天知識書\n\n點選以載入\nShift/Alt+點選或長按開啟「連結聊天知識書」彈窗", |
| 2372 | "Function Tool": "功能工具", | 2372 | "Function Tool": "功能工具", |
| 2373 | "Functions in this category are for advanced users only. Don't click anything if you're not sure about the consequences.": "此類功能僅供高階使用者使用。若不確定後果,請勿點選任何內容。", | 2373 | "Functions in this category are for advanced users only. Don't click anything if you're not sure about the consequences.": "此類功能僅供高階使用者使用。若不確定後果,請勿點選任何內容。", |
| 2374 | "Are you sure you want to delete this user?": "確定要刪除該使用者嗎?", | 2374 | "Are you sure you want to delete this user?": "確定要刪除該使用者嗎?", |
| @@ -24,7 +24,7 @@ import { | |||
| 24 | } from '../script.js'; | 24 | } from '../script.js'; |
| 25 | import { persona_description_positions, power_user } from './power-user.js'; | 25 | import { persona_description_positions, power_user } from './power-user.js'; |
| 26 | import { getTokenCountAsync } from './tokenizers.js'; | 26 | import { getTokenCountAsync } from './tokenizers.js'; |
| 27 | import { PAGINATION_TEMPLATE, clearInfoBlock, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, getCharIndex, isFalseBoolean, isTrueBoolean, onlyUnique, parseJsonFile, setInfoBlock, localizePagination, renderPaginationDropdown, paginationDropdownChangeHandler } from './utils.js'; | 27 | import { PAGINATION_TEMPLATE, clearInfoBlock, debounce, delay, download, ensureImageFormatSupported, flashHighlight, getBase64Async, getCharIndex, isFalseBoolean, isTrueBoolean, onlyUnique, parseJsonFile, setInfoBlock, localizePagination, renderPaginationDropdown, paginationDropdownChangeHandler, addLongPressEvent } from './utils.js'; |
| 28 | import { debounce_timeout } from './constants.js'; | 28 | import { debounce_timeout } from './constants.js'; |
| 29 | import { FILTER_TYPES, FilterHelper } from './filters.js'; | 29 | import { FILTER_TYPES, FilterHelper } from './filters.js'; |
| 30 | import { groups, selected_group } from './group-chats.js'; | 30 | import { groups, selected_group } from './group-chats.js'; |
| @@ -1182,7 +1182,7 @@ async function onPersonaLoreButtonClick(event) { | |||
| 1182 | return; | 1182 | return; |
| 1183 | } | 1183 | } |
| 1184 | 1184 | ||
| 1185 | if (event.altKey && selectedLorebook) { | 1185 | if (selectedLorebook && !event.shiftKey && !event.altKey) { |
| 1186 | openWorldInfoEditor(selectedLorebook); | 1186 | openWorldInfoEditor(selectedLorebook); |
| 1187 | return; | 1187 | return; |
| 1188 | } | 1188 | } |
| @@ -2003,6 +2003,18 @@ export async function initPersonas() { | |||
| 2003 | $('#persona_depth_value').on('input', onPersonaDescriptionDepthValueInput); | 2003 | $('#persona_depth_value').on('input', onPersonaDescriptionDepthValueInput); |
| 2004 | $('#persona_depth_role').on('input', onPersonaDescriptionDepthRoleInput); | 2004 | $('#persona_depth_role').on('input', onPersonaDescriptionDepthRoleInput); |
| 2005 | $('#persona_lore_button').on('click', onPersonaLoreButtonClick); | 2005 | $('#persona_lore_button').on('click', onPersonaLoreButtonClick); |
| 2006 | addLongPressEvent('#persona_lore_button', function () { | ||
| 2007 | onPersonaLoreButtonClick({ shiftKey: true, altKey: false }); | ||
| 2008 | }); | ||
| 2009 | $('#persona-management-dropdown').on('change', async function () { | ||
| 2010 | const target = $(this).find(':selected').attr('id'); | ||
| 2011 | $(this).prop('selectedIndex', 0); | ||
| 2012 | switch (target) { | ||
| 2013 | case 'persona_lorebook_link': | ||
| 2014 | await onPersonaLoreButtonClick({ shiftKey: true, altKey: false }); | ||
| 2015 | break; | ||
| 2016 | } | ||
| 2017 | }); | ||
| 2006 | $('#personas_backup').on('click', onBackupPersonas); | 2018 | $('#personas_backup').on('click', onBackupPersonas); |
| 2007 | $('#personas_restore').on('click', () => $('#personas_restore_input').trigger('click')); | 2019 | $('#personas_restore').on('click', () => $('#personas_restore_input').trigger('click')); |
| 2008 | $('#personas_restore_input').on('change', onPersonasRestoreInput); | 2020 | $('#personas_restore_input').on('change', onPersonasRestoreInput); |
| @@ -2938,3 +2938,46 @@ export function createTimeout(ms, errorMessage = '') { | |||
| 2938 | setTimeout(() => reject(new Error(errorMessage)), ms); | 2938 | setTimeout(() => reject(new Error(errorMessage)), ms); |
| 2939 | }); | 2939 | }); |
| 2940 | } | 2940 | } |
| 2941 | |||
| 2942 | /** | ||
| 2943 | * Registers a long-press (touch hold) event as an alternative to modifier+click. | ||
| 2944 | * Supports event delegation for dynamically created elements. | ||
| 2945 | * @param {string} selector CSS selector for target elements | ||
| 2946 | * @param {function} callback Callback to invoke on long-press, `this` is the matched element | ||
| 2947 | * @param {number} [delay=500] Long-press duration in ms | ||
| 2948 | */ | ||
| 2949 | export function addLongPressEvent(selector, callback, delay = 500) { | ||
| 2950 | let timer = null; | ||
| 2951 | let fired = false; | ||
| 2952 | let target = null; | ||
| 2953 | |||
| 2954 | document.addEventListener('touchstart', function (event) { | ||
| 2955 | const el = event.target.closest(selector); | ||
| 2956 | if (!el) return; | ||
| 2957 | target = el; | ||
| 2958 | fired = false; | ||
| 2959 | timer = setTimeout(() => { | ||
| 2960 | fired = true; | ||
| 2961 | event.preventDefault(); | ||
| 2962 | callback.call(el, event); | ||
| 2963 | }, delay); | ||
| 2964 | }, { passive: false }); | ||
| 2965 | |||
| 2966 | document.addEventListener('touchend', cancelTimer); | ||
| 2967 | document.addEventListener('touchmove', cancelTimer); | ||
| 2968 | document.addEventListener('touchcancel', cancelTimer); | ||
| 2969 | |||
| 2970 | document.addEventListener('click', function (event) { | ||
| 2971 | if (fired && target && target.contains(event.target)) { | ||
| 2972 | event.preventDefault(); | ||
| 2973 | event.stopImmediatePropagation(); | ||
| 2974 | fired = false; | ||
| 2975 | target = null; | ||
| 2976 | } | ||
| 2977 | }, true); | ||
| 2978 | |||
| 2979 | function cancelTimer() { | ||
| 2980 | clearTimeout(timer); | ||
| 2981 | timer = null; | ||
| 2982 | } | ||
| 2983 | } | ||
| @@ -1,7 +1,7 @@ | |||
| 1 | import { Fuse } from '../lib.js'; | 1 | import { Fuse } from '../lib.js'; |
| 2 | 2 | ||
| 3 | import { saveSettings, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles, create_save, createOrEditCharacter, name1 } from '../script.js'; | 3 | import { saveSettings, substituteParams, getRequestHeaders, chat_metadata, this_chid, characters, saveCharacterDebounced, menu_type, eventSource, event_types, getExtensionPromptByName, saveMetadata, getCurrentChatId, extension_prompt_roles, create_save, createOrEditCharacter, name1 } from '../script.js'; |
| 4 | import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex, select2ChoiceClickSubscribe, isFalseBoolean, getSanitizedFilename, checkOverwriteExistingData, getStringHash, parseStringArray, cancelDebounce, findChar, onlyUnique, equalsIgnoreCaseAndAccents, uuidv4, normalizeArray, getUniqueName, logSlashCommandWarn } from './utils.js'; | 4 | import { download, debounce, initScrollHeight, resetScrollHeight, parseJsonFile, extractDataFromPng, getFileBuffer, getCharaFilename, getSortableDelay, escapeRegex, PAGINATION_TEMPLATE, navigation_option, waitUntilCondition, isTrueBoolean, setValueByPath, flashHighlight, select2ModifyOptions, getSelect2OptionId, dynamicSelect2DataViaAjax, highlightRegex, select2ChoiceClickSubscribe, isFalseBoolean, getSanitizedFilename, checkOverwriteExistingData, getStringHash, parseStringArray, cancelDebounce, findChar, onlyUnique, equalsIgnoreCaseAndAccents, uuidv4, normalizeArray, getUniqueName, logSlashCommandWarn, addLongPressEvent } from './utils.js'; |
| 5 | import { extension_settings, getContext } from './extensions.js'; | 5 | import { extension_settings, getContext } from './extensions.js'; |
| 6 | import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js'; | 6 | import { NOTE_MODULE_NAME, metadata_keys, shouldWIAddPrompt } from './authors-note.js'; |
| 7 | import { isMobile } from './RossAscends-mods.js'; | 7 | import { isMobile } from './RossAscends-mods.js'; |
| @@ -5738,7 +5738,7 @@ export function openWorldInfoEditor(worldName) { | |||
| 5738 | export async function assignLorebookToChat(event) { | 5738 | export async function assignLorebookToChat(event) { |
| 5739 | const selectedName = chat_metadata[METADATA_KEY]; | 5739 | const selectedName = chat_metadata[METADATA_KEY]; |
| 5740 | 5740 | ||
| 5741 | if (selectedName && event.altKey) { | 5741 | if (selectedName && !event.shiftKey && !event.altKey) { |
| 5742 | openWorldInfoEditor(selectedName); | 5742 | openWorldInfoEditor(selectedName); |
| 5743 | return; | 5743 | return; |
| 5744 | } | 5744 | } |
| @@ -6110,15 +6110,18 @@ export function initWorldInfo() { | |||
| 6110 | 6110 | ||
| 6111 | const worldName = characters[chid]?.data?.extensions?.world; | 6111 | const worldName = characters[chid]?.data?.extensions?.world; |
| 6112 | const hasEmbed = checkEmbeddedWorld(chid); | 6112 | const hasEmbed = checkEmbeddedWorld(chid); |
| 6113 | if (worldName && world_names.includes(worldName) && !event.shiftKey) { | 6113 | if (worldName && world_names.includes(worldName) && !event.shiftKey && !event.altKey) { |
| 6114 | openWorldInfoEditor(worldName); | 6114 | openWorldInfoEditor(worldName); |
| 6115 | } else if (hasEmbed && !event.shiftKey) { | 6115 | } else if (hasEmbed && !event.shiftKey && !event.altKey) { |
| 6116 | await importEmbeddedWorldInfo(); | 6116 | await importEmbeddedWorldInfo(); |
| 6117 | saveCharacterDebounced(); | 6117 | saveCharacterDebounced(); |
| 6118 | } else { | 6118 | } else { |
| 6119 | openSetWorldMenu(); | 6119 | openSetWorldMenu(); |
| 6120 | } | 6120 | } |
| 6121 | }); | 6121 | }); |
| 6122 | addLongPressEvent('#world_button', function () { | ||
| 6123 | $(this).trigger($.Event('click', { shiftKey: true })); | ||
| 6124 | }); | ||
| 6122 | 6125 | ||
| 6123 | const debouncedWorldInfoSearch = debounce((searchQuery) => { | 6126 | const debouncedWorldInfoSearch = debounce((searchQuery) => { |
| 6124 | worldInfoFilter.setFilterData(FILTER_TYPES.WORLD_INFO_SEARCH, searchQuery); | 6127 | worldInfoFilter.setFilterData(FILTER_TYPES.WORLD_INFO_SEARCH, searchQuery); |
| @@ -6140,6 +6143,14 @@ export function initWorldInfo() { | |||
| 6140 | }); | 6143 | }); |
| 6141 | 6144 | ||
| 6142 | $(document).on('click', '.chat_lorebook_button', assignLorebookToChat); | 6145 | $(document).on('click', '.chat_lorebook_button', assignLorebookToChat); |
| 6146 | addLongPressEvent('.chat_lorebook_button', function () { | ||
| 6147 | assignLorebookToChat({ shiftKey: true, altKey: false }); | ||
| 6148 | }); | ||
| 6149 | |||
| 6150 | $('#group-chat-lorebook-dropdown').on('change', async function () { | ||
| 6151 | $(this).prop('selectedIndex', 0); | ||
| 6152 | await assignLorebookToChat({ shiftKey: true, altKey: false }); | ||
| 6153 | }); | ||
| 6143 | 6154 | ||
| 6144 | // Not needed on mobile | 6155 | // Not needed on mobile |
| 6145 | if (!isMobile()) { | 6156 | if (!isMobile()) { |