mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Improve enlarge inline image
- Make enlarge inline image popup zoomable - Add optional popup class for transparent popups
This commit is contained in:
@@ -135,9 +135,14 @@ dialog {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -8px;
|
top: -8px;
|
||||||
right: -8px;
|
right: -8px;
|
||||||
width: 20px;
|
width: 21px;
|
||||||
height: 20px;
|
height: 21px;
|
||||||
font-size: 19px;
|
font-size: 18px;
|
||||||
|
padding: 2px 3px 3px 2px;
|
||||||
|
|
||||||
filter: brightness(0.4);
|
filter: brightness(0.4);
|
||||||
|
|
||||||
|
/* Fix weird animation issue with font-scaling during popup open */
|
||||||
|
backface-visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,7 +35,7 @@ import {
|
|||||||
extractTextFromOffice,
|
extractTextFromOffice,
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js';
|
import { extension_settings, renderExtensionTemplateAsync, saveMetadataDebounced } from './extensions.js';
|
||||||
import { POPUP_RESULT, POPUP_TYPE, callGenericPopup } from './popup.js';
|
import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from './popup.js';
|
||||||
import { ScraperManager } from './scrapers.js';
|
import { ScraperManager } from './scrapers.js';
|
||||||
import { DragAndDropHandler } from './dragdrop.js';
|
import { DragAndDropHandler } from './dragdrop.js';
|
||||||
|
|
||||||
@@ -566,7 +566,7 @@ export function isExternalMediaAllowed() {
|
|||||||
return !power_user.forbid_external_media;
|
return !power_user.forbid_external_media;
|
||||||
}
|
}
|
||||||
|
|
||||||
function enlargeMessageImage() {
|
async function enlargeMessageImage() {
|
||||||
const mesBlock = $(this).closest('.mes');
|
const mesBlock = $(this).closest('.mes');
|
||||||
const mesId = mesBlock.attr('mesid');
|
const mesId = mesBlock.attr('mesid');
|
||||||
const message = chat[mesId];
|
const message = chat[mesId];
|
||||||
@@ -580,14 +580,28 @@ function enlargeMessageImage() {
|
|||||||
const img = document.createElement('img');
|
const img = document.createElement('img');
|
||||||
img.classList.add('img_enlarged');
|
img.classList.add('img_enlarged');
|
||||||
img.src = imgSrc;
|
img.src = imgSrc;
|
||||||
|
const imgHolder = document.createElement('div');
|
||||||
|
imgHolder.classList.add('img_enlarged_holder');
|
||||||
|
imgHolder.append(img);
|
||||||
const imgContainer = $('<div><pre><code></code></pre></div>');
|
const imgContainer = $('<div><pre><code></code></pre></div>');
|
||||||
imgContainer.prepend(img);
|
imgContainer.prepend(imgHolder);
|
||||||
imgContainer.addClass('img_enlarged_container');
|
imgContainer.addClass('img_enlarged_container');
|
||||||
imgContainer.find('code').addClass('txt').text(title);
|
imgContainer.find('code').addClass('txt').text(title);
|
||||||
const titleEmpty = !title || title.trim().length === 0;
|
const titleEmpty = !title || title.trim().length === 0;
|
||||||
imgContainer.find('pre').toggle(!titleEmpty);
|
imgContainer.find('pre').toggle(!titleEmpty);
|
||||||
addCopyToCodeBlocks(imgContainer);
|
addCopyToCodeBlocks(imgContainer);
|
||||||
callGenericPopup(imgContainer, POPUP_TYPE.DISPLAY, '', { large: true });
|
|
||||||
|
const popup = new Popup(imgContainer, POPUP_TYPE.DISPLAY, '', { large: true, transparent: true });
|
||||||
|
|
||||||
|
popup.dlg.style.width = 'unset';
|
||||||
|
popup.dlg.style.height = 'unset';
|
||||||
|
|
||||||
|
img.addEventListener('click', () => {
|
||||||
|
const shouldZoom = !img.classList.contains('zoomed');
|
||||||
|
img.classList.toggle('zoomed', shouldZoom);
|
||||||
|
});
|
||||||
|
|
||||||
|
await popup.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function deleteMessageImage() {
|
async function deleteMessageImage() {
|
||||||
|
@@ -23,18 +23,19 @@ export const POPUP_RESULT = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} PopupOptions
|
* @typedef {object} PopupOptions
|
||||||
* @property {string|boolean?} [okButton] - Custom text for the OK button, or `true` to use the default (If set, the button will always be displayed, no matter the type of popup)
|
* @property {string|boolean?} [okButton=null] - Custom text for the OK button, or `true` to use the default (If set, the button will always be displayed, no matter the type of popup)
|
||||||
* @property {string|boolean?} [cancelButton] - Custom text for the Cancel button, or `true` to use the default (If set, the button will always be displayed, no matter the type of popup)
|
* @property {string|boolean?} [cancelButton=null] - Custom text for the Cancel button, or `true` to use the default (If set, the button will always be displayed, no matter the type of popup)
|
||||||
* @property {number?} [rows] - The number of rows for the input field
|
* @property {number?} [rows=1] - The number of rows for the input field
|
||||||
* @property {boolean?} [wide] - Whether to display the popup in wide mode (wide screen, 1/1 aspect ratio)
|
* @property {boolean?} [wide=false] - Whether to display the popup in wide mode (wide screen, 1/1 aspect ratio)
|
||||||
* @property {boolean?} [wider] - Whether to display the popup in wider mode (just wider, no height scaling)
|
* @property {boolean?} [wider=false] - Whether to display the popup in wider mode (just wider, no height scaling)
|
||||||
* @property {boolean?} [large] - Whether to display the popup in large mode (90% of screen)
|
* @property {boolean?} [large=false] - Whether to display the popup in large mode (90% of screen)
|
||||||
* @property {boolean?} [allowHorizontalScrolling] - Whether to allow horizontal scrolling in the popup
|
* @property {boolean?} [transparent=false] - Whether to display the popup in transparent mode (no background, border, shadow or anything, only its content)
|
||||||
* @property {boolean?} [allowVerticalScrolling] - Whether to allow vertical scrolling in the popup
|
* @property {boolean?} [allowHorizontalScrolling=false] - Whether to allow horizontal scrolling in the popup
|
||||||
* @property {POPUP_RESULT|number?} [defaultResult] - The default result of this popup when Enter is pressed. Can be changed from `POPUP_RESULT.AFFIRMATIVE`.
|
* @property {boolean?} [allowVerticalScrolling=false] - Whether to allow vertical scrolling in the popup
|
||||||
* @property {CustomPopupButton[]|string[]?} [customButtons] - Custom buttons to add to the popup. If only strings are provided, the buttons will be added with default options, and their result will be in order from `2` onward.
|
* @property {POPUP_RESULT|number?} [defaultResult=POPUP_RESULT.AFFIRMATIVE] - The default result of this popup when Enter is pressed. Can be changed from `POPUP_RESULT.AFFIRMATIVE`.
|
||||||
* @property {(popup: Popup) => boolean?} [onClosing] - Handler called before the popup closes, return `false` to cancel the close
|
* @property {CustomPopupButton[]|string[]?} [customButtons=null] - Custom buttons to add to the popup. If only strings are provided, the buttons will be added with default options, and their result will be in order from `2` onward.
|
||||||
* @property {(popup: Popup) => void?} [onClose] - Handler called after the popup closes, but before the DOM is cleaned up
|
* @property {(popup: Popup) => boolean?} [onClosing=null] - Handler called before the popup closes, return `false` to cancel the close
|
||||||
|
* @property {(popup: Popup) => void?} [onClose=null] - Handler called after the popup closes, but before the DOM is cleaned up
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,7 +106,7 @@ export class Popup {
|
|||||||
* @param {string} [inputValue=''] - The initial value of the input field
|
* @param {string} [inputValue=''] - The initial value of the input field
|
||||||
* @param {PopupOptions} [options={}] - Additional options for the popup
|
* @param {PopupOptions} [options={}] - Additional options for the popup
|
||||||
*/
|
*/
|
||||||
constructor(content, type, inputValue = '', { okButton = null, cancelButton = null, rows = 1, wide = false, wider = false, large = false, allowHorizontalScrolling = false, allowVerticalScrolling = false, defaultResult = POPUP_RESULT.AFFIRMATIVE, customButtons = null, onClosing = null, onClose = null } = {}) {
|
constructor(content, type, inputValue = '', { okButton = null, cancelButton = null, rows = 1, wide = false, wider = false, large = false, transparent = false, allowHorizontalScrolling = false, allowVerticalScrolling = false, defaultResult = POPUP_RESULT.AFFIRMATIVE, customButtons = null, onClosing = null, onClose = null } = {}) {
|
||||||
Popup.util.popups.push(this);
|
Popup.util.popups.push(this);
|
||||||
|
|
||||||
// Make this popup uniquely identifiable
|
// Make this popup uniquely identifiable
|
||||||
@@ -132,6 +133,7 @@ export class Popup {
|
|||||||
if (wide) this.dlg.classList.add('wide_dialogue_popup');
|
if (wide) this.dlg.classList.add('wide_dialogue_popup');
|
||||||
if (wider) this.dlg.classList.add('wider_dialogue_popup');
|
if (wider) this.dlg.classList.add('wider_dialogue_popup');
|
||||||
if (large) this.dlg.classList.add('large_dialogue_popup');
|
if (large) this.dlg.classList.add('large_dialogue_popup');
|
||||||
|
if (transparent) this.dlg.classList.add('transparent_dialogue_popup');
|
||||||
if (allowHorizontalScrolling) this.dlg.classList.add('horizontal_scrolling_dialogue_popup');
|
if (allowHorizontalScrolling) this.dlg.classList.add('horizontal_scrolling_dialogue_popup');
|
||||||
if (allowVerticalScrolling) this.dlg.classList.add('vertical_scrolling_dialogue_popup');
|
if (allowVerticalScrolling) this.dlg.classList.add('vertical_scrolling_dialogue_popup');
|
||||||
|
|
||||||
|
@@ -366,16 +366,6 @@ input[type='checkbox']:focus-visible {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img_enlarged_container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-end;
|
|
||||||
padding: 10px;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img_enlarged_container pre code,
|
|
||||||
.mes_text pre code {
|
.mes_text pre code {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
@@ -3144,6 +3134,12 @@ grammarly-extension {
|
|||||||
min-width: 750px;
|
min-width: 750px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transparent_dialogue_popup {
|
||||||
|
background-color: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
#dialogue_popup .horizontal_scrolling_dialogue_popup {
|
#dialogue_popup .horizontal_scrolling_dialogue_popup {
|
||||||
overflow-x: unset !important;
|
overflow-x: unset !important;
|
||||||
}
|
}
|
||||||
@@ -4493,12 +4489,49 @@ a {
|
|||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.img_enlarged {
|
.img_enlarged_holder {
|
||||||
object-fit: contain;
|
|
||||||
/* Scaling via flex-grow and object-fit only works if we have some kind of base-height set */
|
/* Scaling via flex-grow and object-fit only works if we have some kind of base-height set */
|
||||||
min-height: 120px;
|
min-height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.img_enlarged_holder:has(.zoomed) {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img_enlarged {
|
||||||
|
object-fit: contain;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: zoom-in
|
||||||
|
}
|
||||||
|
|
||||||
|
.img_enlarged.zoomed {
|
||||||
|
object-fit: cover;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
cursor: zoom-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img_enlarged_container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 10px;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img_enlarged_holder::-webkit-scrollbar-corner {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img_enlarged_container pre code {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
.cropper-container {
|
.cropper-container {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user