Layout Update (#4514)
* init * mostly working messy version * css layout, mobile is fixed * revert changes * more of the above * cleanup * revert breaking fixes, cleanup dead code * dead code * delete fallback * spacing * css tweaks and removed getChatBackgroundsList * mobile sizing * revert unrelated changes * use name instead of context * debounce from constants.js * replace if/else * pass images directly * more of the above * buttons * buttons functionality * add default column counts * remove .mobile-only-menu-toggle when clicked (layering fix) * lint * universal column default of 3 * sacrifice firefox for chrome * Restore media query This reverts commit 295a5a81908e58c0bfa5e01fd90fcd62c05471b4. * Add disabled attribute styles for menu_button * use opacity 0, pointer events none instead of display:none * Format styles * Fix type errors * Add blur event handler to close mobile menu when focus is lost --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
+53
-27
@@ -88,6 +88,24 @@ body.reduced-motion #bg_custom {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
/* Control buttons in header */
|
||||
.heading-container-with-controls {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.heading-container-with-controls .heading-text {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.heading-container-with-controls .heading-controls {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
#bg-scrollable-content {
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
@@ -95,57 +113,53 @@ body.reduced-motion #bg_custom {
|
||||
padding: 0 5px 15px;
|
||||
}
|
||||
|
||||
#bg_menu_content,
|
||||
#bg_custom_content {
|
||||
display: grid;
|
||||
gap: 5px;
|
||||
width: 100%;
|
||||
grid-template-columns: repeat(var(--bg-thumb-columns, 5), 1fr);
|
||||
}
|
||||
|
||||
#bg-filter {
|
||||
font-size: calc(var(--mainFontSize) * 0.95);
|
||||
}
|
||||
|
||||
/* Thumbnail Menu & Buttons */
|
||||
/* Thumbnails */
|
||||
.bg_example:hover .BGSampleTitle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.bg_example .mobile-only-menu-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bg_example.flex-container {
|
||||
width: 30%;
|
||||
max-width: 200px;
|
||||
margin: 5px;
|
||||
aspect-ratio: 16/9;
|
||||
.bg_example {
|
||||
cursor: pointer;
|
||||
box-shadow: 0 0 7px var(--black50a);
|
||||
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
border: 0px solid transparent;
|
||||
outline: 2px solid var(--SmartThemeBorderColor);
|
||||
outline-offset: -1px;
|
||||
|
||||
height: auto;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
|
||||
.bg_example.flex-container:focus-visible {
|
||||
.bg_example:focus-visible {
|
||||
outline-offset: inherit;
|
||||
}
|
||||
|
||||
.bg_example_img {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
|
||||
background-image: inherit;
|
||||
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.bg_example .jg-menu {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 8px;
|
||||
gap: 3px;
|
||||
padding: 3px 5px;
|
||||
border-radius: 5px;
|
||||
padding: 3px 3px;
|
||||
z-index: 3;
|
||||
backdrop-filter: blur(4px);
|
||||
border: 1px solid var(--SmartThemeBorderColor);
|
||||
@@ -168,14 +182,14 @@ body.reduced-motion #bg_custom {
|
||||
|
||||
.bg_example .jg-button {
|
||||
display: flex;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
padding: 5px;
|
||||
font-size: 1.1em;
|
||||
border-radius: 6px;
|
||||
border-radius: 5px;
|
||||
transition: background-color var(--animation-duration) ease;
|
||||
}
|
||||
|
||||
@@ -195,6 +209,18 @@ body.reduced-motion #bg_custom {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.thumbnail-clipper {
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.bg_example:not([custom="true"]) .jg-copy,
|
||||
.bg_example[custom="true"] .jg-edit {
|
||||
display: none;
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
#bg_menu_content, #bg_custom_content {
|
||||
grid-template-columns: repeat(var(--bg-thumb-columns, 3), 1fr);
|
||||
}
|
||||
|
||||
.bg_list {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.bg_button {
|
||||
font-size: 15px;
|
||||
}
|
||||
@@ -40,6 +48,11 @@
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.bg_example.mobile-menu-open .mobile-only-menu-toggle {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bg_example .mobile-only-menu-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -57,6 +70,11 @@
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.bg_example .jg-button {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
#bg-header-controls {
|
||||
flex-wrap: wrap;
|
||||
row-gap: 10px;
|
||||
@@ -429,10 +447,6 @@
|
||||
.horde_multiple_hint {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.bg_list {
|
||||
width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
/*landscape mode phones and ipads*/
|
||||
|
||||
+13
-3
@@ -5345,9 +5345,19 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="bg-scrollable-content">
|
||||
<h3 data-i18n="System Backgrounds" class="wide100p textAlignCenter">
|
||||
System Backgrounds
|
||||
</h3>
|
||||
<div class="heading-container-with-controls">
|
||||
<h3 data-i18n="System Backgrounds" class="wide100p textAlignCenter heading-text">
|
||||
System Backgrounds
|
||||
</h3>
|
||||
<div class="heading-controls">
|
||||
<button id="bg_thumb_zoom_out" class="menu_button menu_button_icon" title="Make thumbnails smaller" data-i18n="[title]Make thumbnails smaller">
|
||||
<i class="fa-solid fa-minus"></i>
|
||||
</button>
|
||||
<button id="bg_thumb_zoom_in" class="menu_button menu_button_icon" title="Make thumbnails larger" data-i18n="[title]Make thumbnails larger">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="bg_menu_content" class="bg_list">
|
||||
</div>
|
||||
<h3 data-i18n="Chat Backgrounds" class="wide100p textAlignCenter">
|
||||
|
||||
+157
-78
@@ -3,7 +3,8 @@ import { chat_metadata, eventSource, event_types, generateQuietPrompt, getCurren
|
||||
import { openThirdPartyExtensionMenu, saveMetadataDebounced } from './extensions.js';
|
||||
import { SlashCommand } from './slash-commands/SlashCommand.js';
|
||||
import { SlashCommandParser } from './slash-commands/SlashCommandParser.js';
|
||||
import { createThumbnail, flashHighlight, getBase64Async, stringFormat } from './utils.js';
|
||||
import { createThumbnail, flashHighlight, getBase64Async, stringFormat, debounce } from './utils.js';
|
||||
import { debounce_timeout } from './constants.js';
|
||||
import { t } from './i18n.js';
|
||||
import { Popup } from './popup.js';
|
||||
|
||||
@@ -15,6 +16,11 @@ const PNG_PIXEL = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkY
|
||||
const PNG_PIXEL_BLOB = new Blob([Uint8Array.from(atob(PNG_PIXEL), c => c.charCodeAt(0))], { type: 'image/png' });
|
||||
const PLACEHOLDER_IMAGE = `url('data:image/png;base64,${PNG_PIXEL}')`;
|
||||
|
||||
const THUMBNAIL_COLUMNS_MIN = 2;
|
||||
const THUMBNAIL_COLUMNS_MAX = 8;
|
||||
const THUMBNAIL_COLUMNS_DEFAULT_DESKTOP = 5;
|
||||
const THUMBNAIL_COLUMNS_DEFAULT_MOBILE = 3;
|
||||
|
||||
/**
|
||||
* Storage for frontend-generated background thumbnails.
|
||||
* This is used to store thumbnails for backgrounds that cannot be generated on the server.
|
||||
@@ -45,6 +51,53 @@ export let background_settings = {
|
||||
animation: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a single thumbnail DOM element. The CSS now handles all sizing.
|
||||
* @param {object} imageData - Data for the image (filename, isCustom).
|
||||
* @returns {HTMLElement} The created thumbnail element.
|
||||
*/
|
||||
function createThumbnailElement(imageData) {
|
||||
const bg = imageData.filename;
|
||||
const isCustom = imageData.isCustom;
|
||||
|
||||
const thumbnail = $('#background_template .bg_example').clone();
|
||||
|
||||
const clipper = document.createElement('div');
|
||||
clipper.className = 'thumbnail-clipper lazy-load-background';
|
||||
clipper.style.backgroundImage = PLACEHOLDER_IMAGE;
|
||||
|
||||
const titleElement = thumbnail.find('.BGSampleTitle');
|
||||
clipper.appendChild(titleElement.get(0));
|
||||
thumbnail.append(clipper);
|
||||
|
||||
const url = generateUrlParameter(bg, isCustom);
|
||||
const title = isCustom ? bg.split('/').pop() : bg;
|
||||
const friendlyTitle = title.slice(0, title.lastIndexOf('.'));
|
||||
|
||||
thumbnail.attr('title', title);
|
||||
thumbnail.attr('bgfile', bg);
|
||||
thumbnail.attr('custom', String(isCustom));
|
||||
thumbnail.data('url', url);
|
||||
titleElement.text(friendlyTitle);
|
||||
|
||||
return thumbnail.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the thumbnail column count to the CSS and updates button states.
|
||||
* @param {number} count - The number of columns to display.
|
||||
*/
|
||||
function applyThumbnailColumns(count) {
|
||||
const newCount = Math.max(THUMBNAIL_COLUMNS_MIN, Math.min(count, THUMBNAIL_COLUMNS_MAX));
|
||||
background_settings.thumbnailColumns = newCount;
|
||||
document.documentElement.style.setProperty('--bg-thumb-columns', newCount.toString());
|
||||
|
||||
$('#bg_thumb_zoom_in').prop('disabled', newCount <= THUMBNAIL_COLUMNS_MIN);
|
||||
$('#bg_thumb_zoom_out').prop('disabled', newCount >= THUMBNAIL_COLUMNS_MAX);
|
||||
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
export function loadBackgroundSettings(settings) {
|
||||
let backgroundSettings = settings.background;
|
||||
if (!backgroundSettings || !backgroundSettings.name || !backgroundSettings.url) {
|
||||
@@ -56,6 +109,16 @@ export function loadBackgroundSettings(settings) {
|
||||
if (!Object.hasOwn(backgroundSettings, 'animation')) {
|
||||
backgroundSettings.animation = false;
|
||||
}
|
||||
|
||||
// If a value is already saved, use it. Otherwise, determine default based on screen size.
|
||||
let columns = backgroundSettings.thumbnailColumns;
|
||||
if (!columns) {
|
||||
const isNarrowScreen = window.matchMedia('(max-width: 480px)').matches;
|
||||
columns = isNarrowScreen ? THUMBNAIL_COLUMNS_DEFAULT_MOBILE : THUMBNAIL_COLUMNS_DEFAULT_DESKTOP;
|
||||
}
|
||||
background_settings.thumbnailColumns = columns;
|
||||
applyThumbnailColumns(background_settings.thumbnailColumns);
|
||||
|
||||
setBackground(backgroundSettings.name, backgroundSettings.url);
|
||||
setFittingClass(backgroundSettings.fitting);
|
||||
$('#background_fitting').val(backgroundSettings.fitting);
|
||||
@@ -75,7 +138,7 @@ async function forceSetBackground(backgroundInfo) {
|
||||
list.push(bg);
|
||||
chat_metadata[LIST_METADATA_KEY] = list;
|
||||
saveMetadataDebounced();
|
||||
await getChatBackgroundsList();
|
||||
renderChatBackgrounds();
|
||||
highlightNewBackground(bg);
|
||||
highlightLockedBackground();
|
||||
}
|
||||
@@ -88,28 +151,10 @@ async function onChatChanged() {
|
||||
unsetCustomBackground();
|
||||
}
|
||||
|
||||
await getChatBackgroundsList();
|
||||
renderChatBackgrounds();
|
||||
highlightLockedBackground();
|
||||
}
|
||||
|
||||
async function getChatBackgroundsList() {
|
||||
const list = chat_metadata[LIST_METADATA_KEY];
|
||||
const listEmpty = !Array.isArray(list) || list.length === 0;
|
||||
|
||||
$('#bg_custom_content').empty();
|
||||
$('#bg_chat_hint').toggle(listEmpty);
|
||||
|
||||
if (listEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const bg of list) {
|
||||
const template = await getBackgroundFromTemplate(bg, true);
|
||||
$('#bg_custom_content').append(template);
|
||||
}
|
||||
activateLazyLoader();
|
||||
}
|
||||
|
||||
function getBackgroundPath(fileUrl) {
|
||||
return `backgrounds/${encodeURIComponent(fileUrl)}`;
|
||||
}
|
||||
@@ -257,7 +302,7 @@ async function onCopyToSystemBackgroundClick(e) {
|
||||
const index = list.indexOf(bgNames.oldBg);
|
||||
list.splice(index, 1);
|
||||
saveMetadataDebounced();
|
||||
await getChatBackgroundsList();
|
||||
renderChatBackgrounds();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -382,17 +427,21 @@ async function onDeleteBackgroundClick(e) {
|
||||
list.splice(index, 1);
|
||||
}
|
||||
|
||||
const siblingSelector = '.bg_example:not(#form_bg_download)';
|
||||
const nextBg = bgToDelete.next(siblingSelector);
|
||||
const prevBg = bgToDelete.prev(siblingSelector);
|
||||
const anyBg = $(siblingSelector);
|
||||
if (bg === background_settings.name) {
|
||||
const siblingSelector = '.bg_example';
|
||||
const nextBg = bgToDelete.next(siblingSelector);
|
||||
const prevBg = bgToDelete.prev(siblingSelector);
|
||||
|
||||
if (nextBg.length > 0) {
|
||||
nextBg.trigger('click');
|
||||
} else if (prevBg.length > 0) {
|
||||
prevBg.trigger('click');
|
||||
} else {
|
||||
$(anyBg[Math.floor(Math.random() * anyBg.length)]).trigger('click');
|
||||
if (nextBg.length > 0) {
|
||||
nextBg.trigger('click');
|
||||
} else if (prevBg.length > 0) {
|
||||
prevBg.trigger('click');
|
||||
} else {
|
||||
const anyOtherBg = $('.bg_example').not(bgToDelete).first();
|
||||
if (anyOtherBg.length > 0) {
|
||||
anyOtherBg.trigger('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bgToDelete.remove();
|
||||
@@ -404,7 +453,7 @@ async function onDeleteBackgroundClick(e) {
|
||||
}
|
||||
|
||||
if (isCustom) {
|
||||
await getChatBackgroundsList();
|
||||
renderChatBackgrounds();
|
||||
saveMetadataDebounced();
|
||||
}
|
||||
}
|
||||
@@ -445,6 +494,47 @@ async function autoBackgroundCommand() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the system backgrounds gallery.
|
||||
* @param {string[]} [backgrounds] - Optional filtered list of backgrounds.
|
||||
*/
|
||||
function renderSystemBackgrounds(backgrounds) {
|
||||
const sourceList = backgrounds || [];
|
||||
const container = $('#bg_menu_content');
|
||||
container.empty();
|
||||
|
||||
if (sourceList.length === 0) return;
|
||||
|
||||
sourceList.forEach(bg => {
|
||||
const imageData = { filename: bg, isCustom: false };
|
||||
const thumbnail = createThumbnailElement(imageData);
|
||||
container.append(thumbnail);
|
||||
});
|
||||
|
||||
activateLazyLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the chat-specific (custom) backgrounds gallery.
|
||||
* @param {string[]} [backgrounds] - Optional filtered list of backgrounds.
|
||||
*/
|
||||
function renderChatBackgrounds(backgrounds) {
|
||||
const sourceList = backgrounds ?? (chat_metadata[LIST_METADATA_KEY] || []);
|
||||
const container = $('#bg_custom_content');
|
||||
container.empty();
|
||||
$('#bg_chat_hint').toggle(!sourceList.length);
|
||||
|
||||
if (sourceList.length === 0) return;
|
||||
|
||||
sourceList.forEach(bg => {
|
||||
const imageData = { filename: bg, isCustom: true };
|
||||
const thumbnail = createThumbnailElement(imageData);
|
||||
container.append(thumbnail);
|
||||
});
|
||||
|
||||
activateLazyLoader();
|
||||
}
|
||||
|
||||
export async function getBackgrounds() {
|
||||
const response = await fetch('/api/backgrounds/all', {
|
||||
method: 'POST',
|
||||
@@ -454,12 +544,7 @@ export async function getBackgrounds() {
|
||||
if (response.ok) {
|
||||
const { images, config } = await response.json();
|
||||
Object.assign(THUMBNAIL_CONFIG, config);
|
||||
$('#bg_menu_content').children('div').remove();
|
||||
for (const bg of images) {
|
||||
const template = await getBackgroundFromTemplate(bg, false);
|
||||
$('#bg_menu_content').append(template);
|
||||
}
|
||||
activateLazyLoader();
|
||||
renderSystemBackgrounds(images);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,14 +566,19 @@ function activateLazyLoader() {
|
||||
lazyLoadObserver = new IntersectionObserver((entries, observer) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.target instanceof HTMLElement && entry.isIntersecting) {
|
||||
const target = entry.target;
|
||||
const bg = target.getAttribute('bgfile');
|
||||
const isCustom = target.getAttribute('custom') === 'true';
|
||||
resolveImageUrl(bg, isCustom)
|
||||
.then(url => { target.style.backgroundImage = url; })
|
||||
.catch(() => { target.style.backgroundImage = PLACEHOLDER_IMAGE; });
|
||||
target.classList.remove('lazy-load-background');
|
||||
observer.unobserve(target);
|
||||
const clipper = entry.target;
|
||||
const parentThumbnail = clipper.closest('.bg_example');
|
||||
|
||||
if (parentThumbnail) {
|
||||
const bg = parentThumbnail.getAttribute('bgfile');
|
||||
const isCustom = parentThumbnail.getAttribute('custom') === 'true';
|
||||
resolveImageUrl(bg, isCustom)
|
||||
.then(url => { clipper.style.backgroundImage = url; })
|
||||
.catch(() => { clipper.style.backgroundImage = PLACEHOLDER_IMAGE; });
|
||||
}
|
||||
|
||||
clipper.classList.remove('lazy-load-background');
|
||||
observer.unobserve(clipper);
|
||||
}
|
||||
});
|
||||
}, options);
|
||||
@@ -529,28 +619,6 @@ async function resolveImageUrl(bg, isCustom) {
|
||||
return `url("${thumbnailUrl}")`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a background template
|
||||
* @param {string} bg Path to background
|
||||
* @param {boolean} isCustom Whether the background is custom
|
||||
* @returns {Promise<JQuery<HTMLElement>>} Background template
|
||||
*/
|
||||
async function getBackgroundFromTemplate(bg, isCustom) {
|
||||
const template = $('#background_template .bg_example').clone();
|
||||
const url = generateUrlParameter(bg, isCustom);
|
||||
const title = isCustom ? bg.split('/').pop() : bg;
|
||||
const friendlyTitle = title.slice(0, title.lastIndexOf('.'));
|
||||
|
||||
template.attr('title', title);
|
||||
template.attr('bgfile', bg);
|
||||
template.attr('custom', String(isCustom));
|
||||
template.data('url', url);
|
||||
template.addClass('lazy-load-background');
|
||||
template.css('background-image', PLACEHOLDER_IMAGE);
|
||||
template.find('.BGSampleTitle').text(friendlyTitle);
|
||||
return template;
|
||||
}
|
||||
|
||||
async function setBackground(bg, url) {
|
||||
$('#bg1').css('background-image', url);
|
||||
background_settings.name = bg;
|
||||
@@ -688,17 +756,17 @@ function setFittingClass(fitting) {
|
||||
}
|
||||
|
||||
function onBackgroundFilterInput() {
|
||||
const filterValue = String($(this).val()).toLowerCase();
|
||||
$('#bg_menu_content > div').each(function () {
|
||||
const $bgContent = $(this);
|
||||
if ($bgContent.attr('title').toLowerCase().includes(filterValue)) {
|
||||
$bgContent.show();
|
||||
} else {
|
||||
$bgContent.hide();
|
||||
}
|
||||
const filterValue = String($('#bg-filter').val()).toLowerCase();
|
||||
$('#bg_menu_content > .bg_example, #bg_custom_content > .bg_example').each(function () {
|
||||
const $bg = $(this);
|
||||
const title = $bg.attr('title') || '';
|
||||
const hasMatch = title.toLowerCase().includes(filterValue);
|
||||
$bg.toggle(hasMatch);
|
||||
});
|
||||
}
|
||||
|
||||
const debouncedOnBackgroundFilterInput = debounce(onBackgroundFilterInput, debounce_timeout.standard);
|
||||
|
||||
export function initBackgrounds() {
|
||||
eventSource.on(event_types.CHAT_CHANGED, onChatChanged);
|
||||
eventSource.on(event_types.FORCE_SET_BACKGROUND, forceSetBackground);
|
||||
@@ -715,6 +783,11 @@ export function initBackgrounds() {
|
||||
$context.addClass('mobile-menu-open');
|
||||
}
|
||||
})
|
||||
.off('blur', '.bg_example.mobile-menu-open').on('blur', '.bg_example.mobile-menu-open', function () {
|
||||
if (!$(this).is(':focus-within')) {
|
||||
$(this).removeClass('mobile-menu-open');
|
||||
}
|
||||
})
|
||||
.off('click', '.jg-button').on('click', '.jg-button', function (e) {
|
||||
e.stopPropagation();
|
||||
const action = $(this).data('action');
|
||||
@@ -738,9 +811,15 @@ export function initBackgrounds() {
|
||||
}
|
||||
});
|
||||
|
||||
$('#bg_thumb_zoom_in').on('click', () => {
|
||||
applyThumbnailColumns(background_settings.thumbnailColumns - 1);
|
||||
});
|
||||
$('#bg_thumb_zoom_out').on('click', () => {
|
||||
applyThumbnailColumns(background_settings.thumbnailColumns + 1);
|
||||
});
|
||||
$('#auto_background').on('click', autoBackgroundCommand);
|
||||
$('#add_bg_button').on('change', onBackgroundUploadSelected);
|
||||
$('#bg-filter').on('input', onBackgroundFilterInput);
|
||||
$('#bg-filter').on('input', () => debouncedOnBackgroundFilterInput());
|
||||
SlashCommandParser.addCommandObject(SlashCommand.fromProps({
|
||||
name: 'lockbg',
|
||||
callback: () => onLockBackgroundClick(new CustomEvent('click')),
|
||||
|
||||
+3
-2
@@ -2940,6 +2940,7 @@ select option:not(:checked) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.menu_button[disabled],
|
||||
.menu_button.disabled {
|
||||
filter: brightness(75%) grayscale(1);
|
||||
opacity: 0.5;
|
||||
@@ -3675,8 +3676,8 @@ grammarly-extension {
|
||||
min-width: calc(1.25em + 12px);
|
||||
}
|
||||
|
||||
.menu_button:not(.disabled):hover,
|
||||
.menu_button:not(.disabled).active {
|
||||
.menu_button:not(.disabled):not([disabled]):hover,
|
||||
.menu_button:not(.disabled):not([disabled]).active {
|
||||
background-color: var(--white30a);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user