PageSourceSearch

https://aurora-c9c22.web.app/js/cloudManager.js?v=837e45446c

js aurora-c9c22.web.app collected 2026-10-03 12:17:26 UTC 2,597 bytes, 78 lines download raw bytes

1// cloudManager.js
2import { sendDiscordEvent } from './utils/sendDiscordEvent.js';
3import { sendDiscordError } from './utils/sendDiscordError.js';
4import { showCloudJokeModal } from './cloudJokeModal.js';
5// Cloud tiles: the whole world at zoom 2 (16 tiles, fetched the first time the
6// layer is shown), plus the tiles covering the view when zoomed in closer.
7const CLOUD_TILES = {
8    globalLevel: 2,
9    maxLevel: 7,
10    maxTiles: 24,
11    alpha: 0.99,
12    credit: 'Clouds: OpenWeatherMap',
13};
14
15export class CloudCoverManager {
16    constructor(globe, apiKey) {
17        this.globe = globe;
18        this.apiKey = apiKey;
19        this.cloudLayer = null;
20        this.cloudsEnabled = false;
21        this.provider = 'openweathermap';
22        this.hasLoggedDiscovery = false;
23        this.init();
24    }
25
26    init() {
27        if (this.provider === 'openweathermap') {
28            this.addOpenWeatherClouds();
29        }
30        this.setupToggleButton();
31    }
32
33    addOpenWeatherClouds() {
34        try {
35            // Nothing is fetched until the layer is shown.
36            this.cloudLayer = this.globe.setTileOverlay({
37                ...CLOUD_TILES,
38                url: `https://tile.openweathermap.org/map/clouds_new/{z}/{x}/{y}.png?appid=${this.apiKey}`,
39                show: false,
40            });
41            console.log('✓ OpenWeatherMap Cloud cover layer loaded');
42        } catch (error) {
43            console.error('Failed to load cloud cover:', error);
44            sendDiscordError("Cloud API Failure", error, { provider: 'OpenWeatherMap' });
45        }
46    }
47
48    toggle() {
49        if (!this.cloudLayer) return;
50        if (!this.cloudsEnabled) {
51            showCloudJokeModal();
52        }
53        this.cloudsEnabled = !this.cloudsEnabled;
54        this.cloudLayer.show = this.cloudsEnabled;
55
56        if (this.cloudsEnabled && !this.hasLoggedDiscovery) {
57            sendDiscordEvent(
58                "☁️ Feature Discovered: Clouds", 
59                "A user toggled the Cloud Cover layer for the first time this session.",
60                { provider: this.provider }
61            );
62            this.hasLoggedDiscovery = true; 
63        }
64        
65        const btn = document.getElementById('cloudToggle');
66        if (btn) {
67            btn.setAttribute('aria-pressed', this.cloudsEnabled);
68            btn.title = this.cloudsEnabled ? 'Hide Cloud Cover' : 'Show Cloud Cover';
69        }
70    }
71
72    setupToggleButton() {
73        const btn = document.getElementById('cloudToggle');
74        if (btn) {
75            btn.addEventListener('click', () => this.toggle());
76        }
77    }
78}

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.