mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import { POPUP_RESULT, POPUP_TYPE, Popup } from './popup.js';
 | |
| 
 | |
| /** @type {Popup} */
 | |
| let loaderPopup;
 | |
| 
 | |
| let preloaderYoinked = false;
 | |
| 
 | |
| export function showLoader() {
 | |
|     // Two loaders don't make sense. Don't await, we can overlay the old loader while it closes
 | |
|     if (loaderPopup) loaderPopup.complete(POPUP_RESULT.CANCELLED);
 | |
| 
 | |
|     loaderPopup = new Popup(`
 | |
|         <div id="loader">
 | |
|             <div id="load-spinner" class="fa-solid fa-gear fa-spin fa-3x"></div>
 | |
|         </div>`, POPUP_TYPE.DISPLAY, null, { transparent: true, animation: 'none' });
 | |
| 
 | |
|     // No close button, loaders are not closable
 | |
|     loaderPopup.closeButton.style.display = 'none';
 | |
| 
 | |
|     loaderPopup.show();
 | |
| }
 | |
| 
 | |
| export async function hideLoader() {
 | |
|     if (!loaderPopup) {
 | |
|         console.warn('There is no loader showing to hide');
 | |
|         return Promise.resolve();
 | |
|     }
 | |
| 
 | |
|     return new Promise((resolve) => {
 | |
|         const spinner = $('#load-spinner');
 | |
|         if (!spinner.length) {
 | |
|             console.warn('Spinner element not found, skipping animation');
 | |
|             cleanup();
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         // Check if transitions are enabled
 | |
|         const transitionDuration = spinner[0] ? getComputedStyle(spinner[0]).transitionDuration : '0s';
 | |
|         const hasTransitions = parseFloat(transitionDuration) > 0;
 | |
| 
 | |
|         if (hasTransitions) {
 | |
|             Promise.race([
 | |
|                 new Promise((r) => setTimeout(r, 500)), // Fallback timeout
 | |
|                 new Promise((r) => spinner.one('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', r)),
 | |
|             ]).finally(cleanup);
 | |
|         } else {
 | |
|             cleanup();
 | |
|         }
 | |
| 
 | |
|         function cleanup() {
 | |
|             $('#loader').remove();
 | |
|             // Yoink preloader entirely; it only exists to cover up unstyled content while loading JS
 | |
|             // If it's present, we remove it once and then it's gone.
 | |
|             yoinkPreloader();
 | |
| 
 | |
|             loaderPopup.complete(POPUP_RESULT.AFFIRMATIVE)
 | |
|                 .catch((err) => console.error('Error completing loaderPopup:', err))
 | |
|                 .finally(() => {
 | |
|                     loaderPopup = null;
 | |
|                     resolve();
 | |
|                 });
 | |
|         }
 | |
| 
 | |
|         // Apply the styles
 | |
|         spinner.css({
 | |
|             'filter': 'blur(15px)',
 | |
|             'opacity': '0',
 | |
|         });
 | |
|     });
 | |
| }
 | |
| 
 | |
| function yoinkPreloader() {
 | |
|     if (preloaderYoinked) return;
 | |
|     document.getElementById('preloader').remove();
 | |
|     preloaderYoinked = true;
 | |
| }
 |