PageSourceSearch

https://progressiveplants.com/2026projects/updategardenplan/js/loading-puns.js?v=20250824

js progressiveplants.com collected 2026-09-30 17:22:58 UTC 10,825 bytes, 310 lines download raw bytes

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.