1/** 2 * Loading Puns Manager 3 * Provides entertaining plant-themed messages during loading 4 */ 5 6const LoadingPuns = { 7 // Plant puns for loading messages 8 messages: [ 9 "Growing your garden catalog... ð±", 10 "Photosynthesizing your plant data... âï¸", 11 "Watering the database... ð§", 12 "Planting seeds of knowledge... ð°", 13 "Cultivating the perfect selection... ð¿", 14 "Pruning for peak performance... âï¸", 15 "Leaf it to us, we're loading... ð", 16 "Rooting for your perfect garden... ð³", 17 "Blooming marvelous things take time... ð¸", 18 "Un-be-leaf-able plants coming right up... ð", 19 "Getting to the root of great gardening... ðª´", 20 "Sprouting new possibilities... ð±", 21 "Fertilizing your imagination... ð»", 22 "Harvesting the best varieties... ð¾", 23 "Branching out to find perfect plants... ð²", 24 "Sowing the seeds of success... ð°", 25 "Growing strong like an oak... ð³", 26 "Blossoming with possibilities... ðº", 27 "Mint to be... loading your favorites... ð¿", 28 "Thistle be worth the wait... ðµ", 29 "We're not garden variety - loading premium plants... ð¹", 30 "Lettuce load your plants... ð¥¬", 31 "Aloe you vera much - preparing your garden... ðµ", 32 "Time to turnip the beet - loading... ðµ", 33 "You grow, girl! Loading plants... ð", 34 "Plant-astic things are loading... â¨", 35 "Succ-ess is growing... ðµ", 36 "Life would succ without plants... ðª´", 37 "Stay rooted while we load... ð³", 38 "Every plant has its thorn... loading roses... ð¹" 39 ], 40 41 // Phase-specific messages 42 phaseMessages: { 43 initial: [ 44 "Preparing your garden experience... ð", 45 "Welcome to Progressive Plants... ð¿", 46 "Getting things ready for you... â³" 47 ], 48 catalog: [ 49 "Loading 2900+ amazing plants... ð", 50 "Gathering our plant collection... ðº", 51 "Assembling the plant catalog... ð" 52 ], 53 stock: [ 54 "Checking real-time availability... ð", 55 "Verifying stock levels... ð¦", 56 "Finding what's available now... â " 57 ], 58 almost: [ 59 "Almost ready to bloom... ð¸", 60 "Just a moment more... â°", 61 "Finishing touches... â¨" 62 ] 63 }, 64 65 currentMessageIndex: 0, 66 messageInterval: null, 67 progressInterval: null, 68 startTime: null, 69 totalExpectedTime: 3000, // Expected load time in ms 70 71 /** 72 * Initialize the loading puns system 73 */ 74 init() { 75 this.startTime = Date.now(); 76 this.startMessageRotation(); 77 this.startProgressAnimation(); 78 }, 79 80 /** 81 * Start rotating through pun messages 82 */ 83 startMessageRotation() { 84 const textElement = document.getElementById('loadingText'); 85 if (!textElement) return; 86 87 // Clear any existing interval first to prevent conflicts 88 if (this.messageInterval) { 89 clearInterval(this.messageInterval); 90 this.messageInterval = null; 91 } 92 93 // Show first message immediately 94 textElement.textContent = this.getRandomMessage(); 95 96 // Check if we're on mobile for slower rotation 97 const isMobile = window.innerWidth <= 768; 98 const rotationInterval = isMobile ? 5000 : 3000; // 5 seconds on mobile, 3 on desktop 99 const fadeTime = isMobile ? 500 : 300; // Slower fade on mobile 100 101 console.log(`[LoadingPuns] Starting message rotation - Mobile: ${isMobile}, Interval: ${rotationInterval}ms`); 102 103 // Rotate messages based on device type 104 this.messageInterval = setInterval(() => { 105 // Fade out 106 textElement.style.opacity = '0.6'; 107 108 setTimeout(() => { 109 // Change message 110 textElement.textContent = this.getNextMessage(); 111 // Fade in 112 textElement.style.opacity = '1'; 113 }, fadeTime); 114 }, rotationInterval); 115 }, 116 117 /** 118 * Get a random message 119 */ 120 getRandomMessage() { 121 const randomIndex = Math.floor(Math.random() * this.messages.length); 122 return this.messages[randomIndex]; 123 }, 124 125 /** 126 * Get the next message in sequence 127 */ 128 getNextMessage() { 129 this.currentMessageIndex = (this.currentMessageIndex + 1) % this.messages.length; 130 return this.messages[this.currentMessageIndex]; 131 }, 132 133 /** 134 * Get phase-specific message 135 */ 136 getPhaseMessage(phase) { 137 const messages = this.phaseMessages[phase] || this.messages; 138 return messages[Math.floor(Math.random() * messages.length)]; 139 }, 140 141 /** 142 * Start progress bar animation 143 */ 144 startProgressAnimation() { 145 const progressContainer = document.getElementById('loadingProgress'); 146 const progressFill = document.getElementById('progressFill'); 147 const progressText = document.getElementById('progressText'); 148 149 if (!progressContainer || !progressFill) return; 150 151 // Clear any existing progress interval first 152 if (this.progressInterval) { 153 clearInterval(this.progressInterval); 154 this.progressInterval = null; 155 } 156 157 // Show progress bar on mobile or slow connections 158 const isMobile = window.innerWidth <= 768; 159 const isSlowConnection = navigator.connection?.effectiveType === '2g' || 160 navigator.connection?.effectiveType === '3g'; 161 162 if (isMobile || isSlowConnection) { 163 progressContainer.style.display = 'block'; 164 } 165 166 let progress = 0; 167 168 // Adjust timing and smoothness based on device (isMobile already declared above) 169 const updateInterval = isMobile ? 250 : 100; // Slower updates on mobile 170 const baseIncrement = isMobile ? 1.5 : 2; // Smaller increments on mobile 171 const randomVariation = isMobile ? 1 : 3; // Less variation on mobile 172
173 console.log(`[LoadingPuns] Starting progress animation - Mobile: ${isMobile}, Interval: ${updateInterval}ms`); 174 175 this.progressInterval = setInterval(() => { 176 progress = Math.min(progress + baseIncrement + Math.random() * randomVariation, 95); 177 178 progressFill.style.width = progress + '%'; 179 180 // Update progress text based on progress 181 if (progress < 25) { 182 progressText.textContent = 'Initializing...'; 183 } else if (progress < 50) { 184 progressText.textContent = 'Loading plant catalog...'; 185 } else if (progress < 75) { 186 progressText.textContent = 'Checking availability...'; 187 } else if (progress < 95) { 188 progressText.textContent = 'Almost there...'; 189 } else { 190 progressText.textContent = 'Finalizing...'; 191 } 192 }, updateInterval); 193 }, 194 195 /** 196 * Update loading phase 197 */ 198 updatePhase(phase, customMessage = null) { 199 const textElement = document.getElementById('loadingText'); 200 if (!textElement) return; 201 202 const message = customMessage || this.getPhaseMessage(phase); 203 204 // Use consistent timing with mobile considerations 205 const isMobile = window.innerWidth <= 768; 206 const fadeTime = isMobile ? 500 : 300; 207 208 // Animate message change 209 textElement.style.opacity = '0.6'; 210 setTimeout(() => { 211 textElement.textContent = message; 212 textElement.style.opacity = '1'; 213 }, fadeTime); 214 }, 215 216 /** 217 * Complete loading with success message 218 */ 219 complete() { 220 const progressFill = document.getElementById('progressFill'); 221 const progressText = document.getElementById('progressText'); 222 const textElement = document.getElementById('loadingText'); 223 224 // Clear intervals 225 if (this.messageInterval) { 226 clearInterval(this.messageInterval); 227 } 228 if (this.progressInterval) { 229 clearInterval(this.progressInterval); 230 } 231 232 // Complete progress bar 233 if (progressFill) { 234 progressFill.style.width = '100%'; 235 } 236 if (progressText) { 237 progressText.textContent = 'Ready!'; 238 } 239 240 // Show success message 241 if (textElement) { 242 textElement.textContent = 'Your garden awaits! ð»'; 243 } 244 245 // Calculate actual load time 246 const loadTime = Date.now() - this.startTime; 247 console.log(`[LoadingPuns] Loading completed in ${loadTime}ms`); 248 }, 249 250 /** 251 * Show loading overlay with puns 252 */ 253 show(initialMessage = null) { 254 const overlay = document.getElementById('loadingOverlay'); 255 if (!overlay) return; 256 257 // Only initialize if overlay is not already visible to prevent multiple inits 258 const wasVisible = overlay.style.display === 'flex'; 259 260 overlay.style.display = 'flex'; 261 262 if (!wasVisible) { 263 console.log(`[LoadingPuns] Initializing loading overlay - Mobile: ${window.innerWidth <= 768}`); 264 // Reset and start only if not already running 265 this.currentMessageIndex = 0; 266 this.init(); 267 268 // Debug: Check what animation is actually applied 269 setTimeout(() => { 270 const logo = document.querySelector('.spinning-logo'); 271 if (logo) { 272 const computedStyle = window.getComputedStyle(logo); 273 const animationName = computedStyle.animationName; 274 const animationDuration = computedStyle.animationDuration; 275 console.log(`[LoadingPuns] DEBUG - Applied animation: ${animationName}, Duration: ${animationDuration}`); 276 } 277 }, 100); 278 } 279 280 if (initialMessage) { 281 const textElement = document.getElementById('loadingText'); 282 if (textElement) { 283 textElement.textContent = initialMessage; 284 } 285 } 286 }, 287 288 /** 289 * Hide loading overlay 290 */ 291 hide() {
292 const overlay = document.getElementById('loadingOverlay'); 293 if (!overlay) return; 294 295 // Complete animations first 296 this.complete(); 297 298 // Fade out overlay 299 setTimeout(() => { 300 overlay.style.opacity = '0'; 301 setTimeout(() => { 302 overlay.style.display = 'none'; 303 overlay.style.opacity = '1'; 304 }, 400); 305 }, 500); 306 } 307}; 308 309// Export for use 310window.LoadingPuns = LoadingPuns;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.