|
10 | 10 | </head> |
11 | 11 | <body> |
12 | 12 | <div id="aladin-lite-div" aria-label="Interactive FITS viewer"></div> |
13 | | - <div id="aladin-overlay" class="overlay" role="status" aria-live="polite"> |
14 | | - <span id="overlay-message">Loading the NASA sky map…</span> |
15 | | - </div> |
16 | 13 | <aside class="hud" aria-live="polite"> |
17 | 14 | <p class="title">NASA FITS Explorer</p> |
18 | 15 | <p class="status" id="status-message">Select a FITS source to start exploring.</p> |
|
63 | 60 | <script type="module"> |
64 | 61 | import { A } from 'https://aladin.cds.unistra.fr/AladinLite/api/v3/latest/aladin.min.js'; |
65 | 62 |
|
66 | | - const overlay = document.getElementById('aladin-overlay'); |
67 | | - const overlayMessage = document.getElementById('overlay-message'); |
68 | 63 | const statusMessage = document.getElementById('status-message'); |
69 | 64 | const errorBox = document.getElementById('aladin-error'); |
70 | 65 | const fileInput = document.getElementById('fits-file'); |
|
83 | 78 | } |
84 | 79 | : null; |
85 | 80 |
|
86 | | - function setOverlay(message) { |
87 | | - overlayMessage.textContent = message; |
88 | | - overlay.classList.remove('hidden'); |
89 | | - } |
90 | | - |
91 | | - function clearOverlay() { |
92 | | - overlay.classList.add('hidden'); |
93 | | - overlayMessage.textContent = 'Loading the NASA sky map…'; |
94 | | - } |
95 | | - |
96 | 81 | function showError(message) { |
97 | 82 | errorBox.textContent = message; |
98 | 83 | errorBox.classList.remove('hidden'); |
|
160 | 145 | const label = options.label || deriveLabel(source); |
161 | 146 |
|
162 | 147 | clearError(); |
163 | | - setOverlay(`Loading ${label}…`); |
| 148 | + const loadTimeout = window.setTimeout(() => { |
| 149 | + if (requestId !== currentRequestId) { |
| 150 | + return; |
| 151 | + } |
| 152 | + console.warn(`FITS load timed out: ${label}`); |
| 153 | + showError('The FITS file is taking longer than expected to respond. Please try again or use a different source.'); |
| 154 | + }, options.timeout ?? 20000); |
| 155 | + |
| 156 | + const clearLoadState = () => { |
| 157 | + window.clearTimeout(loadTimeout); |
| 158 | + }; |
164 | 159 |
|
165 | 160 | const handleSuccess = (ra, dec, fov, image) => { |
166 | 161 | if (requestId !== currentRequestId) { |
167 | 162 | return; |
168 | 163 | } |
| 164 | + clearLoadState(); |
169 | 165 | configureImage(image, options.colormap); |
170 | 166 | focusOnImage(ra, dec, fov); |
171 | 167 | updateStatus(label, fov); |
172 | | - clearOverlay(); |
173 | 168 | }; |
174 | 169 |
|
175 | 170 | const handleError = (error) => { |
176 | 171 | if (requestId !== currentRequestId) { |
177 | 172 | return; |
178 | 173 | } |
| 174 | + clearLoadState(); |
179 | 175 | console.error('Failed to load FITS data', error); |
180 | | - clearOverlay(); |
181 | 176 | showError('Unable to load the FITS data. Please verify the file or URL and try again.'); |
182 | 177 | }; |
183 | 178 |
|
184 | 179 | try { |
185 | 180 | const result = aladinInstance.displayFITS(source, options.params || {}, handleSuccess, handleError); |
186 | 181 | if (result && typeof result.then === 'function') { |
187 | | - result.catch(handleError); |
| 182 | + result.catch(handleError).finally(clearLoadState); |
188 | 183 | } |
189 | 184 | } catch (error) { |
190 | 185 | handleError(error); |
|
240 | 235 | if (DEFAULT_SAMPLE) { |
241 | 236 | loadFits(DEFAULT_SAMPLE.url, DEFAULT_SAMPLE); |
242 | 237 | } else { |
243 | | - clearOverlay(); |
244 | 238 | updateStatus(null); |
245 | 239 | } |
246 | 240 | } catch (error) { |
247 | 241 | console.error('Aladin Lite failed to initialise', error); |
248 | 242 | showError('The Aladin Lite viewer could not be initialised. Please refresh the page.'); |
249 | | - clearOverlay(); |
250 | 243 | } |
251 | 244 | } |
252 | 245 |
|
|
0 commit comments