File size: 7,083 Bytes
046723b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Socket.IO client-side integration for changedetection.io

$(document).ready(function () {

    function bindSocketHandlerButtonsEvents(socket) {
        $('.ajax-op').on('click.socketHandlerNamespace', function (e) {
            e.preventDefault();
            const op = $(this).data('op');
            const uuid = $(this).closest('tr').data('watch-uuid');
            
            console.log(`Socket.IO: Sending watch operation '${op}' for UUID ${uuid}`);
            
            // Emit the operation via Socket.IO
            socket.emit('watch_operation', {
                'op': op,
                'uuid': uuid
            });
            
            return false;
        });


        $('#checkbox-operations button').on('click.socketHandlerNamespace', function (e) {
            e.preventDefault();
            const op = $(this).val();
            const checkedUuids = $('input[name="uuids"]:checked').map(function () {
                return this.value.trim();
            }).get();
            console.log(`Socket.IO: Sending watch operation '${op}' for UUIDs:`, checkedUuids);
            socket.emit('checkbox-operation', {
                op: op,
                uuids: checkedUuids,
                extra_data: $('#op_extradata').val() // Set by the alert() handler
            });
            $('input[name="uuids"]:checked').prop('checked', false);
            $('#check-all:checked').prop('checked', false);
            return false;
        });

    }


    // Only try to connect if authentication isn't required or user is authenticated
    // The 'is_authenticated' variable will be set in the template
    if (typeof is_authenticated !== 'undefined' ? is_authenticated : true) {
        // Try to create the socket connection to the SocketIO server - if it fails, the site will still work normally
        try {
            // Connect to Socket.IO on the same host/port, with path from template
            const socket = io({
                path: socketio_url,  // This will be the path prefix like "/app/socket.io" from the template
                transports: ['polling', 'websocket'],  // Try WebSocket but fall back to polling
                reconnectionDelay: 1000,
                reconnectionAttempts: 15
            });

            // Connection status logging
            socket.on('connect', function () {
                $('#realtime-conn-error').hide();
                console.log('Socket.IO connected with path:', socketio_url);
                console.log('Socket transport:', socket.io.engine.transport.name);
                bindSocketHandlerButtonsEvents(socket);
            });

            socket.on('connect_error', function(error) {
                console.error('Socket.IO connection error:', error);
            });

            socket.on('connect_timeout', function() {
                console.error('Socket.IO connection timeout');
            });

            socket.on('error', function(error) {
                console.error('Socket.IO error:', error);
            });

            socket.on('disconnect', function (reason) {
                console.log('Socket.IO disconnected, reason:', reason);
                $('.ajax-op').off('.socketHandlerNamespace');
                $('#realtime-conn-error').show();
            });

            socket.on('queue_size', function (data) {
                console.log(`${data.event_timestamp} - Queue size update: ${data.q_length}`);
                // Update queue size display if implemented in the UI
            })

            // Listen for operation results
            socket.on('operation_result', function (data) {
                if (data.success) {
                    console.log(`Socket.IO: Operation '${data.operation}' completed successfully for UUID ${data.uuid}`);
                } else {
                    console.error(`Socket.IO: Operation failed: ${data.error}`);
                    alert("There was a problem processing the request: " + data.error);
                }
            });

            socket.on('notification_event', function (data) {
                console.log(`Stub handler for notification_event ${data.watch_uuid}`)
            });

            // Listen for periodically emitted watch data
            console.log('Adding watch_update event listener');

            socket.on('watch_update', function (data) {
                const watch = data.watch;
                const general_stats = data.general_stats;

                // Log the entire watch object for debugging
                console.log('!!! WATCH UPDATE EVENT RECEIVED !!!');
                console.log(`${watch.event_timestamp} - Watch update ${watch.uuid} - Checking now - ${watch.checking_now} - UUID in URL ${window.location.href.includes(watch.uuid)}`);
                console.log('Watch data:', watch);
                console.log('General stats:', general_stats);
                
                // Updating watch table rows
                const $watchRow = $('tr[data-watch-uuid="' + watch.uuid + '"]');
                console.log('Found watch row elements:', $watchRow.length);
                
                if ($watchRow.length) {
                    $($watchRow).toggleClass('checking-now', watch.checking_now);
                    $($watchRow).toggleClass('queued', watch.queued);
                    $($watchRow).toggleClass('unviewed', watch.unviewed);
                    $($watchRow).toggleClass('has-error', watch.has_error);
                    $($watchRow).toggleClass('notification_muted', watch.notification_muted);
                    $($watchRow).toggleClass('paused', watch.paused);
                    $($watchRow).toggleClass('single-history', watch.history_n === 1);
                    $($watchRow).toggleClass('multiple-history', watch.history_n >= 2);

                    $('td.title-col .error-text', $watchRow).html(watch.error_text)

                    $('td.last-changed', $watchRow).text(watch.last_changed_text)

                    $('td.last-checked .innertext', $watchRow).text(watch.last_checked_text)
                    $('td.last-checked', $watchRow).data('timestamp', watch.last_checked).data('fetchduration', watch.fetch_time);
                    $('td.last-checked', $watchRow).data('eta_complete', watch.last_checked + watch.fetch_time);
                    
                    console.log('Updated UI for watch:', watch.uuid);
                }

                // Tabs at bottom of list
                $('#post-list-mark-views').toggleClass("has-unviewed", general_stats.has_unviewed);
                $('#post-list-with-errors').toggleClass("has-error", general_stats.count_errors !== 0)
                $('#post-list-with-errors a').text(`With errors (${ general_stats.count_errors })`);

                $('body').toggleClass('checking-now', watch.checking_now && window.location.href.includes(watch.uuid));
            });

        } catch (e) {
            // If Socket.IO fails to initialize, just log it and continue
            console.log('Socket.IO initialization error:', e);
        }
    }
});