Add button to re-caption message image
| @@ -5686,10 +5686,11 @@ | |||
| 5686 | <div class="mes_edit_cancel menu_button fa-solid fa-xmark" title="Cancel" data-i18n="[title]Cancel"></div> | 5686 | <div class="mes_edit_cancel menu_button fa-solid fa-xmark" title="Cancel" data-i18n="[title]Cancel"></div> |
| 5687 | </div> | 5687 | </div> |
| 5688 | </div> | 5688 | </div> |
| 5689 | <div class=mes_text></div> | 5689 | <div class="mes_text"></div> |
| 5690 | <div class="mes_img_container"> | 5690 | <div class="mes_img_container"> |
| 5691 | <div class="mes_img_controls"> | 5691 | <div class="mes_img_controls"> |
| 5692 | <div title="Enlarge" class="right_menu_button fa-lg fa-solid fa-magnifying-glass mes_img_enlarge" data-i18n="[title]Enlarge"></div> | 5692 | <div title="Enlarge" class="right_menu_button fa-lg fa-solid fa-magnifying-glass mes_img_enlarge" data-i18n="[title]Enlarge"></div> |
| 5693 | <div title="Caption" class="right_menu_button fa-lg fa-solid fa-envelope-open-text mes_img_caption" data-i18n="[title]Caption"></div> | ||
| 5693 | <div title="Delete" class="right_menu_button fa-lg fa-solid fa-trash-can mes_img_delete" data-i18n="[title]Delete"></div> | 5694 | <div title="Delete" class="right_menu_button fa-lg fa-solid fa-trash-can mes_img_delete" data-i18n="[title]Delete"></div> |
| 5694 | </div> | 5695 | </div> |
| 5695 | <img class="mes_img" src="" /> | 5696 | <img class="mes_img" src="" /> |
| @@ -2079,14 +2079,23 @@ export function updateMessageBlock(messageId, message) { | |||
| 2079 | appendMediaToMessage(message, messageElement); | 2079 | appendMediaToMessage(message, messageElement); |
| 2080 | } | 2080 | } |
| 2081 | 2081 | ||
| 2082 | export function appendMediaToMessage(mes, messageElement) { | 2082 | /** |
| 2083 | * Appends image or file to the message element. | ||
| 2084 | * @param {object} mes Message object | ||
| 2085 | * @param {JQuery<HTMLElement>} messageElement Message element | ||
| 2086 | * @param {boolean} [adjustScroll=true] Whether to adjust the scroll position after appending the media | ||
| 2087 | */ | ||
| 2088 | export function appendMediaToMessage(mes, messageElement, adjustScroll = true) { | ||
| 2083 | // Add image to message | 2089 | // Add image to message |
| 2084 | if (mes.extra?.image) { | 2090 | if (mes.extra?.image) { |
| 2085 | const chatHeight = $('#chat').prop('scrollHeight'); | 2091 | const chatHeight = $('#chat').prop('scrollHeight'); |
| 2086 | const image = messageElement.find('.mes_img'); | 2092 | const image = messageElement.find('.mes_img'); |
| 2087 | const text = messageElement.find('.mes_text'); | 2093 | const text = messageElement.find('.mes_text'); |
| 2088 | const isInline = !!mes.extra?.inline_image; | 2094 | const isInline = !!mes.extra?.inline_image; |
| 2089 | image.on('load', function () { | 2095 | image.off('load').on('load', function () { |
| 2096 | if (!adjustScroll) { | ||
| 2097 | return; | ||
| 2098 | } | ||
| 2090 | const scrollPosition = $('#chat').scrollTop(); | 2099 | const scrollPosition = $('#chat').scrollTop(); |
| 2091 | const newChatHeight = $('#chat').prop('scrollHeight'); | 2100 | const newChatHeight = $('#chat').prop('scrollHeight'); |
| 2092 | const diff = newChatHeight - chatHeight; | 2101 | const diff = newChatHeight - chatHeight; |
| @@ -5636,7 +5645,7 @@ export async function renameCharacter(name = null, { silent = false, renameChats | |||
| 5636 | } | 5645 | } |
| 5637 | } | 5646 | } |
| 5638 | catch (error) { | 5647 | catch (error) { |
| 5639 | // Reloading to prevent data corruption | 5648 | // Reloading to prevent data corruption |
| 5640 | if (!silent) await callPopup('Something went wrong. The page will be reloaded.', 'text'); | 5649 | if (!silent) await callPopup('Something went wrong. The page will be reloaded.', 'text'); |
| 5641 | else toastr.error('Something went wrong. The page will be reloaded.', 'Rename Character'); | 5650 | else toastr.error('Something went wrong. The page will be reloaded.', 'Rename Character'); |
| 5642 | 5651 | ||
| @@ -1,6 +1,6 @@ | |||
| 1 | import { ensureImageFormatSupported, getBase64Async, isTrueBoolean, saveBase64AsFile } from '../../utils.js'; | 1 | import { ensureImageFormatSupported, getBase64Async, isTrueBoolean, saveBase64AsFile } from '../../utils.js'; |
| 2 | import { getContext, getApiUrl, doExtrasFetch, extension_settings, modules, renderExtensionTemplateAsync } from '../../extensions.js'; | 2 | import { getContext, getApiUrl, doExtrasFetch, extension_settings, modules, renderExtensionTemplateAsync } from '../../extensions.js'; |
| 3 | import { callPopup, eventSource, event_types, getRequestHeaders, saveSettingsDebounced, substituteParamsExtended } from '../../../script.js'; | 3 | import { appendMediaToMessage, callPopup, eventSource, event_types, getRequestHeaders, saveChatConditional, saveSettingsDebounced, substituteParamsExtended } from '../../../script.js'; |
| 4 | import { getMessageTimeStamp } from '../../RossAscends-mods.js'; | 4 | import { getMessageTimeStamp } from '../../RossAscends-mods.js'; |
| 5 | import { SECRET_KEYS, secret_state } from '../../secrets.js'; | 5 | import { SECRET_KEYS, secret_state } from '../../secrets.js'; |
| 6 | import { getMultimodalCaption } from '../shared.js'; | 6 | import { getMultimodalCaption } from '../shared.js'; |
| @@ -514,6 +514,15 @@ jQuery(async function () { | |||
| 514 | eventSource.on(event_types.MESSAGE_SENT, onMessageEvent); | 514 | eventSource.on(event_types.MESSAGE_SENT, onMessageEvent); |
| 515 | eventSource.on(event_types.MESSAGE_FILE_EMBEDDED, onMessageEvent); | 515 | eventSource.on(event_types.MESSAGE_FILE_EMBEDDED, onMessageEvent); |
| 516 | 516 | ||
| 517 | $(document).on('click', '.mes_img_caption', async function () { | ||
| 518 | const messageBlock = $(this).closest('.mes'); | ||
| 519 | const index = Number(messageBlock.attr('mesid')); | ||
| 520 | const data = getContext().chat[index]; | ||
| 521 | await captionExistingMessage(data); | ||
| 522 | appendMediaToMessage(data, messageBlock, false); | ||
| 523 | await saveChatConditional(); | ||
| 524 | }); | ||
| 525 | |||
| 517 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'caption', | 526 | SlashCommandParser.addCommandObject(SlashCommand.fromProps({ name: 'caption', |
| 518 | callback: captionCommandCallback, | 527 | callback: captionCommandCallback, |
| 519 | returns: 'caption', | 528 | returns: 'caption', |
| @@ -548,4 +557,6 @@ jQuery(async function () { | |||
| 548 | </div> | 557 | </div> |
| 549 | `, | 558 | `, |
| 550 | })); | 559 | })); |
| 560 | |||
| 561 | document.body.classList.add('caption'); | ||
| 551 | }); | 562 | }); |
| @@ -4481,7 +4481,8 @@ a { | |||
| 4481 | } | 4481 | } |
| 4482 | 4482 | ||
| 4483 | .mes_img_controls .right_menu_button { | 4483 | .mes_img_controls .right_menu_button { |
| 4484 | filter: brightness(80%); | 4484 | filter: brightness(90%); |
| 4485 | text-shadow: 1px 1px var(--SmartThemeShadowColor) !important; | ||
| 4485 | padding: 1px; | 4486 | padding: 1px; |
| 4486 | height: 1.25em; | 4487 | height: 1.25em; |
| 4487 | width: 1.25em; | 4488 | width: 1.25em; |
| @@ -4506,6 +4507,10 @@ a { | |||
| 4506 | display: flex; | 4507 | display: flex; |
| 4507 | } | 4508 | } |
| 4508 | 4509 | ||
| 4510 | body:not(.caption) .mes_img_caption { | ||
| 4511 | display: none; | ||
| 4512 | } | ||
| 4513 | |||
| 4509 | .img_enlarged_holder { | 4514 | .img_enlarged_holder { |
| 4510 | /* Scaling via flex-grow and object-fit only works if we have some kind of base-height set */ | 4515 | /* Scaling via flex-grow and object-fit only works if we have some kind of base-height set */ |
| 4511 | min-height: 120px; | 4516 | min-height: 120px; |