PageSourceSearch

https://www.stmartinschurch.gg/js/component/progressBar.js?v=5

js stmartinschurch.gg collected 2026-10-04 02:08:13 UTC 4,046 bytes, 127 lines download raw bytes

1window.appComponents.progressBar = (taskId, stoppable = false) => ({
2    // --- STATE ---
3    percent: 0,
4    statusText: 'Initializing...',
5    hasFailed: false,
6    eventSource: null,
7    isComplete: false,
8    isStopping: false,
9    isStoppable: stoppable,
10    isTerminated: false, // Keep the anti-race-condition flag
11
12    init() {
13        const url = `/lib/static/progress_stream.php?taskId=${taskId}`;
14        this.eventSource = new EventSource(url);
15
16        this.eventSource.onmessage = (event) => {
17            const data = JSON.parse(event.data);
18            
19            if (data.done) {
20                if (data.error) {
21                    this.handleTaskError(data);
22                } else {
23                    this.handleTaskComplete(data);
24                }
25            } else {
26                this.handleProgressUpdate(data);
27            }
28        };
29
30        this.eventSource.onerror = (error) => {
31            // --- LOGGING ---
32            console.error('[PROGRESS JS - ONERROR]', { error, isTerminated: this.isTerminated });
33            if (this.isTerminated) return; // Ignore intentional closures
34
35            if (!this.isComplete && !this.hasFailed) {
36                this.hasFailed = true;
37                this.statusText = 'Connection to the server was lost.';
38            }
39            this.cleanup();
40        };
41    },
42    
43    handleProgressUpdate(data) {
44        this.percent = data.percent;
45        this.statusText = data.status;
46    },
47
48    handleTaskComplete(data) {
49        this.isComplete = true;
50        this.percent = 100;
51        this.statusText = data.status || "Complete!";
52        this.cleanup(); 
53
54        setTimeout(() => {
55            Alpine.store('modals').close();
56            this.routeOnCompleteAction(data.result || { action: 'close' });
57        }, 750);
58    },
59    
60    handleTaskError(data) {
61        this.hasFailed = true;
62        this.percent = 100;
63        this.statusText = data.error || 'The task failed with an unknown error.';
64        this.cleanup();
65    },
66
67    cleanup() {
68        if (this.eventSource) {
69            this.isTerminated = true;
70            this.eventSource.close();
71            this.eventSource = null;
72        }
73    },
74
75    closeAndCleanup() {
76        this.cleanup();
77        Alpine.store('modals').close();
78    },
79
80    /**
81     * The rest of your code is correct.
82     */
83    routeOnCompleteAction(onComplete) {
84        switch (onComplete.action) {
85            case 'successAndRedirect':
86                Alpine.store('modals').showSuccessAndRedirect(onComplete.message, onComplete.url);
87                break;
88            case 'flashAndRedirect':
89            case 'redirect':
90                if (onComplete.url) window.location.href = onComplete.url;
91                break;
92            case 'triggerEvents':
93                if (onComplete.events && typeof onComplete.events === 'object') {
94                    Object.keys(onComplete.events).forEach(eventName => {
95                        const eventDetail = onComplete.events[eventName];
96                        htmx.trigger(document.body, eventName, eventDetail);
97                    });
98                }                
99                break;
100            case 'close':
101            default:
102                // Do nothing
103                break;
104        }
105    },
106
107    stopTask() {
108        // Prevent multiple clicks or stopping a finished task
109        if (this.isStopping || this.isComplete) return;
110
111        this.isStopping = true;
112        this.statusText = "Requesting to stop...";
113
114        // Send a simple, fire-and-forget request to the stop endpoint
115        fetch('/lib/static/task_stop.php', {
116            method: 'POST',
117            headers: { 'Content-Type': 'application/json' },
118            body: JSON.stringify({ taskId: taskId })
119        })
120        .catch(error => {
121            console.error("Stop request failed:", error);
122            // Re-enable the button if the request fails
123            this.isStopping = false;
124            this.statusText = "Failed to send stop request."; 
125        });
126    },
127});

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.