Pure CSS drawer animations
| @@ -10317,68 +10317,19 @@ function doDrawerOpenClick() { | |||
| 10317 | doNavbarIconClick.call(drawerToggle); | 10317 | doNavbarIconClick.call(drawerToggle); |
| 10318 | } | 10318 | } |
| 10319 | 10319 | ||
| 10320 | |||
| 10321 | // Helper for animating open/close (opacity only) | ||
| 10322 | async function animateDrawer($el, open, displayStyle = 'block', onEnd) { | ||
| 10323 | //const slideOptions = getSlideToggleOptions(); | ||
| 10324 | const duration = 250; | ||
| 10325 | const easing = 'swing'; | ||
| 10326 | $el.stop(true, true); | ||
| 10327 | |||
| 10328 | if (open) { | ||
| 10329 | $el.css({ display: displayStyle, opacity: 0 }); | ||
| 10330 | $el.animate( | ||
| 10331 | { opacity: 1 }, | ||
| 10332 | { | ||
| 10333 | duration, | ||
| 10334 | easing, | ||
| 10335 | complete: function () { | ||
| 10336 | $el.css({ opacity: '', display: displayStyle }); | ||
| 10337 | if (typeof onEnd === 'function') onEnd(this); | ||
| 10338 | }, | ||
| 10339 | }, | ||
| 10340 | ); | ||
| 10341 | } else { | ||
| 10342 | $el.animate( | ||
| 10343 | { opacity: 0 }, | ||
| 10344 | { | ||
| 10345 | duration, | ||
| 10346 | easing, | ||
| 10347 | complete: function () { | ||
| 10348 | $el.css({ display: 'none', opacity: '0' }); | ||
| 10349 | if (typeof onEnd === 'function') onEnd(this); | ||
| 10350 | }, | ||
| 10351 | }, | ||
| 10352 | ); | ||
| 10353 | } | ||
| 10354 | } | ||
| 10355 | |||
| 10356 | /** | 10320 | /** |
| 10357 | * Event handler to open or close a navbar drawer when a navbar icon is clicked. | 10321 | * Event handler to open or close a navbar drawer when a navbar icon is clicked. |
| 10358 | * Handles click events on .drawer-toggle elements. | 10322 | * Handles click events on .drawer-toggle elements. |
| 10359 | * @returns {void} | 10323 | * @returns {Promise<void>} |
| 10360 | */ | 10324 | */ |
| 10361 | // ...existing code... | ||
| 10362 | export async function doNavbarIconClick() { | 10325 | export async function doNavbarIconClick() { |
| 10363 | //console.warn('called for, ', $(this)); | ||
| 10364 | const icon = $(this).find('.drawer-icon'); | 10326 | const icon = $(this).find('.drawer-icon'); |
| 10365 | const drawer = $(this).parent().find('.drawer-content'); | 10327 | const drawer = $(this).parent().find('.drawer-content'); |
| 10366 | if (drawer.hasClass('resizing')) { return; } | ||
| 10367 | const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer'); | 10328 | const drawerWasOpenAlready = $(this).parent().find('.drawer-content').hasClass('openDrawer'); |
| 10368 | const targetDrawerID = $(this).parent().find('.drawer-content').attr('id'); | 10329 | const targetDrawerID = $(this).parent().find('.drawer-content').attr('id'); |
| 10369 | const pinnedDrawerClicked = drawer.hasClass('pinnedOpen'); | ||
| 10370 | 10330 | ||
| 10371 | if (!drawerWasOpenAlready) { // to open the drawer | 10331 | if (!drawerWasOpenAlready) { |
| 10372 | // Close all open drawers except pinned ones | ||
| 10373 | const $openDrawers = $('.openDrawer:not(.pinnedOpen)'); | 10332 | const $openDrawers = $('.openDrawer:not(.pinnedOpen)'); |
| 10374 | for (const el of $openDrawers) { | ||
| 10375 | $(el).addClass('resizing'); | ||
| 10376 | await animateDrawer($(el), false, undefined, function (el) { | ||
| 10377 | $(el).closest('.drawer-content').removeClass('resizing'); | ||
| 10378 | }); | ||
| 10379 | } | ||
| 10380 | |||
| 10381 | // Toggle icon and drawer classes | ||
| 10382 | const $openIcons = $('.openIcon:not(.drawerPinnedOpen)'); | 10333 | const $openIcons = $('.openIcon:not(.drawerPinnedOpen)'); |
| 10383 | for (const iconEl of $openIcons) { | 10334 | for (const iconEl of $openIcons) { |
| 10384 | $(iconEl).toggleClass('closedIcon openIcon'); | 10335 | $(iconEl).toggleClass('closedIcon openIcon'); |
| @@ -10389,21 +10340,9 @@ export async function doNavbarIconClick() { | |||
| 10389 | icon.toggleClass('openIcon closedIcon'); | 10340 | icon.toggleClass('openIcon closedIcon'); |
| 10390 | drawer.toggleClass('openDrawer closedDrawer'); | 10341 | drawer.toggleClass('openDrawer closedDrawer'); |
| 10391 | 10342 | ||
| 10392 | // Open the target drawer | ||
| 10393 | const $drawerContents = $(this).closest('.drawer').find('.drawer-content'); | ||
| 10394 | for (const el of $drawerContents) { | ||
| 10395 | $(el).addClass('resizing'); | ||
| 10396 | if (targetDrawerID === 'right-nav-panel') { | 10343 | if (targetDrawerID === 'right-nav-panel') { |
| 10397 | await animateDrawer($(el), true, 'flex', function (el) { | ||
| 10398 | $(el).closest('.drawer-content').removeClass('resizing'); | ||
| 10399 | favsToHotswap(); | 10344 | favsToHotswap(); |
| 10400 | $('#rm_print_characters_block').trigger('scroll'); | 10345 | $('#rm_print_characters_block').trigger('scroll'); |
| 10401 | }); | ||
| 10402 | } else { | ||
| 10403 | await animateDrawer($(el), true, undefined, function (el) { | ||
| 10404 | $(el).closest('.drawer-content').removeClass('resizing'); | ||
| 10405 | }); | ||
| 10406 | } | ||
| 10407 | } | 10346 | } |
| 10408 | 10347 | ||
| 10409 | // Set the height of "autoSetHeight" textareas within the drawer to their scroll height | 10348 | // Set the height of "autoSetHeight" textareas within the drawer to their scroll height |
| @@ -10414,31 +10353,12 @@ export async function doNavbarIconClick() { | |||
| 10414 | return; | 10353 | return; |
| 10415 | } | 10354 | } |
| 10416 | } | 10355 | } |
| 10417 | 10356 | } else if (drawerWasOpenAlready) { | |
| 10418 | } else if (drawerWasOpenAlready) { // to close manually | ||
| 10419 | console.warn('saw drawer was already open'); | ||
| 10420 | icon.toggleClass('closedIcon openIcon'); | 10357 | icon.toggleClass('closedIcon openIcon'); |
| 10421 | |||
| 10422 | if (pinnedDrawerClicked) { | ||
| 10423 | $(drawer).addClass('resizing').each((_, el) => { | ||
| 10424 | animateDrawer($(el), false, undefined, function (el) { | ||
| 10425 | el.classList.remove('resizing'); | ||
| 10426 | }); | ||
| 10427 | }); | ||
| 10428 | } | ||
| 10429 | else { | ||
| 10430 | console.warn('not pinned drawer'); | ||
| 10431 | $('.openDrawer').not('.pinnedOpen').addClass('resizing').each((_, el) => { | ||
| 10432 | animateDrawer($(el), false, undefined, function (el) { | ||
| 10433 | el.closest('.drawer-content').classList.remove('resizing'); | ||
| 10434 | }); | ||
| 10435 | }); | ||
| 10436 | } | ||
| 10437 | |||
| 10438 | drawer.toggleClass('closedDrawer openDrawer'); | 10358 | drawer.toggleClass('closedDrawer openDrawer'); |
| 10439 | } | 10359 | } |
| 10440 | } | 10360 | } |
| 10441 | // ...existing code... | 10361 | |
| 10442 | function addDebugFunctions() { | 10362 | function addDebugFunctions() { |
| 10443 | const doBackfill = async () => { | 10363 | const doBackfill = async () => { |
| 10444 | for (const message of chat) { | 10364 | for (const message of chat) { |
| @@ -12064,7 +11984,7 @@ jQuery(async function () { | |||
| 12064 | $('.drawer-toggle').on('click', doNavbarIconClick); | 11984 | $('.drawer-toggle').on('click', doNavbarIconClick); |
| 12065 | 11985 | ||
| 12066 | $('html').on('touchstart mousedown', async function (e) { | 11986 | $('html').on('touchstart mousedown', async function (e) { |
| 12067 | var clickTarget = $(e.target); | 11987 | const clickTarget = $(e.target); |
| 12068 | 11988 | ||
| 12069 | if (isExportPopupOpen | 11989 | if (isExportPopupOpen |
| 12070 | && clickTarget.closest('#export_button').length == 0 | 11990 | && clickTarget.closest('#export_button').length == 0 |
| @@ -12085,27 +12005,19 @@ jQuery(async function () { | |||
| 12085 | '#toast-container', | 12005 | '#toast-container', |
| 12086 | '.select2-results', | 12006 | '.select2-results', |
| 12087 | ]; | 12007 | ]; |
| 12008 | |||
| 12088 | for (const id of forbiddenTargets) { | 12009 | for (const id of forbiddenTargets) { |
| 12089 | if (clickTarget.closest(id).length > 0) { | 12010 | if (clickTarget.closest(id).length > 0) { |
| 12090 | return; | 12011 | return; |
| 12091 | } | 12012 | } |
| 12092 | } | 12013 | } |
| 12093 | 12014 | ||
| 12094 | |||
| 12095 | // This autocloses open drawers that are not pinned if a click happens inside the app which does not target them. | 12015 | // This autocloses open drawers that are not pinned if a click happens inside the app which does not target them. |
| 12096 | var targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length; | 12016 | const targetParentHasOpenDrawer = clickTarget.parents('.openDrawer').length; |
| 12097 | if (!clickTarget.hasClass('drawer-icon') && !clickTarget.hasClass('openDrawer')) { | 12017 | if (!clickTarget.hasClass('drawer-icon') && !clickTarget.hasClass('openDrawer')) { |
| 12098 | const $openDrawers = $('.openDrawer').not('.pinnedOpen'); | 12018 | const $openDrawers = $('.openDrawer').not('.pinnedOpen'); |
| 12099 | if ($openDrawers.length && targetParentHasOpenDrawer === 0) { | 12019 | if ($openDrawers.length && targetParentHasOpenDrawer === 0) { |
| 12100 | // Animate close for each open drawer | 12020 | // Toggle icon and drawer classes |
| 12101 | for (const el of $openDrawers) { | ||
| 12102 | $(el).addClass('resizing'); | ||
| 12103 | // Use the same animateDrawer helper as in doNavbarIconClick | ||
| 12104 | await animateDrawer($(el), false, undefined, function (el) { | ||
| 12105 | $(el).closest('.drawer-content').removeClass('resizing'); | ||
| 12106 | }); | ||
| 12107 | } | ||
| 12108 | // Toggle icon and drawer classes after animation | ||
| 12109 | $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon'); | 12021 | $('.openIcon').not('.drawerPinnedOpen').toggleClass('closedIcon openIcon'); |
| 12110 | $openDrawers.toggleClass('closedDrawer openDrawer'); | 12022 | $openDrawers.toggleClass('closedDrawer openDrawer'); |
| 12111 | } | 12023 | } |
| @@ -14,6 +14,7 @@ | |||
| 14 | @import url(css/data-maid.css); | 14 | @import url(css/data-maid.css); |
| 15 | 15 | ||
| 16 | :root { | 16 | :root { |
| 17 | interpolate-size: allow-keywords; | ||
| 17 | --doc-height: 100%; | 18 | --doc-height: 100%; |
| 18 | --transparent: rgba(0, 0, 0, 0); | 19 | --transparent: rgba(0, 0, 0, 0); |
| 19 | 20 | ||
| @@ -2805,7 +2806,6 @@ input[type="file"] { | |||
| 2805 | } | 2806 | } |
| 2806 | 2807 | ||
| 2807 | #rm_extensions_block { | 2808 | #rm_extensions_block { |
| 2808 | display: none; | ||
| 2809 | overflow-y: auto; | 2809 | overflow-y: auto; |
| 2810 | } | 2810 | } |
| 2811 | 2811 | ||
| @@ -2934,7 +2934,6 @@ select option:not(:checked) { | |||
| 2934 | /*#######################################################################*/ | 2934 | /*#######################################################################*/ |
| 2935 | 2935 | ||
| 2936 | #rm_api_block { | 2936 | #rm_api_block { |
| 2937 | display: none; | ||
| 2938 | overflow-y: auto; | 2937 | overflow-y: auto; |
| 2939 | } | 2938 | } |
| 2940 | 2939 | ||
| @@ -5402,6 +5401,21 @@ body:has(#character_popup.open) #top-settings-holder:has(.drawer-content.openDra | |||
| 5402 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | 5401 | backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); |
| 5403 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); | 5402 | -webkit-backdrop-filter: blur(calc(var(--SmartThemeBlurStrength))); |
| 5404 | /* z-index: 1000 !important; */ | 5403 | /* z-index: 1000 !important; */ |
| 5404 | height: 0; | ||
| 5405 | transition-property: height, display; | ||
| 5406 | transition-duration: var(--animation-duration); | ||
| 5407 | transition-timing-function: ease-in-out; | ||
| 5408 | transition-behavior: allow-discrete; | ||
| 5409 | } | ||
| 5410 | |||
| 5411 | .drawer-content.openDrawer { | ||
| 5412 | display: block; | ||
| 5413 | height: auto; | ||
| 5414 | height: calc-size(auto, size); | ||
| 5415 | |||
| 5416 | @starting-style { | ||
| 5417 | height: 0; | ||
| 5418 | } | ||
| 5405 | } | 5419 | } |
| 5406 | 5420 | ||
| 5407 | body.movingUI .inline-drawer-maximize { | 5421 | body.movingUI .inline-drawer-maximize { |