Skip to content
Snippets Groups Projects
Select Git revision
  • 84ab1725b31ae06a3d443d60584f7a2108953bfe
  • main default protected
  • step-3263
  • feature/plugins-cli
  • feature/vite
  • step-2484-peerreview
  • biest/issue-5051
  • tests/simplify-jsonapi-tests
  • fix/typo-in-1a70031
  • feature/broadcasting
  • database-seeders-and-factories
  • feature/peer-review-2
  • feature-feedback-jsonapi
  • feature/peerreview
  • feature/balloon-plus
  • feature/stock-images-unsplash
  • tic-2588
  • 5.0
  • 5.2
  • biest/unlock-blocks
  • biest-1514
21 results

I18n_formattedInput.php

Blame
  • Forked from Stud.IP / Stud.IP
    Source project has a limited visibility.
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    jsupdater.js 7.14 KiB
    /* ------------------------------------------------------------------------
     * JSUpdater - periodically polls for new data from server
     * ------------------------------------------------------------------------
     * Exposes the following method on the global STUDIP.JSUpdater object:
     *
     * - start()
     * - stop()
     * - register(index, callback, data)
     * - unregister(index)
     *
     * Refer to the according function definitions for further info.
     * ------------------------------------------------------------------------ */
    import { $gettext } from './gettext.js';
    import Dialog from './dialog.js';
    
    let active = false;
    let lastAjaxDuration = 200; //ms of the duration of an ajax-call
    let currentDelayFactor = 0;
    let lastJsonResult = null;
    let dateOfLastCall = +new Date(); // Get milliseconds of date object
    let serverTimestamp = STUDIP.server_timestamp;
    let ajaxRequest = null;
    let timeout = null;
    let registeredHandlers = {};
    
    // Reset json memory, used to delay polling if consecutive requests always
    // return the same result
    function resetJSONMemory(json) {
        if (json.hasOwnProperty('server_timestamp')) {
            delete json.server_timestamp;
        }
        json = JSON.stringify(json);
        if (json !== lastJsonResult) {
            currentDelayFactor = 0;
        }
        lastJsonResult = json;
    }
    
    // Process returned json object by calling registered handlers
    function process(json) {
        for (const [index, value] of Object.entries(json)) {
            // Set timestamp
            if (index === 'server_timestamp') {
                serverTimestamp = value;
            } else {
                // Call registered handler callback by index
                if (index in registeredHandlers) {
                    registeredHandlers[index].callback(value);
                }
            }
        }
    
        // Reset json memory
        resetJSONMemory(json);
    }
    
    // Registers next poll
    function registerNextPoll() {
        // Calculate smallest registered polling interval (but no more than 60 seconds)
        let interval = 60000;
        for (const [index, handler] of Object.entries(registeredHandlers)) {
            if (handler.interval < interval) {
                interval = handler.interval;
            }
        }
    
        // Define delay by last poll request (respond to load on server) and
        // current delay factor (respond to user activity)
        var delay = (interval || lastAjaxDuration * 15) * Math.pow(1.33, currentDelayFactor);
    
        // Clear any previously scheduled polling
        window.clearTimeout(timeout);
        timeout = window.setTimeout(poll, delay);
    
        // Increase current delay factor
        currentDelayFactor += 1;
    }
    
    // Collect data for polling
    function collectData() {
        var data = {};
        // Pull data from all registered handlers, either by collecting the data
        // itself or by calling the appropriate function
        for (const [index, handler] of Object.entries(registeredHandlers)) {
            if (handler.data) {
                const thisData = $.isFunction(handler.data) ? handler.data() : handler.data;
                if (thisData !== null && !$.isEmptyObject(thisData)) {
                    data[index] = thisData;
                }
            }
        }
    
        return data;
    }
    
    // User activity handler
    function userActivityHandler() {
        currentDelayFactor = 0;
        if (+new Date() - dateOfLastCall > 5000) {
            poll(true);
        }
    }
    
    // Window activity handler
    function windowActivityHandler(event) {
        if (event.type === 'blur') {
            // Increase delay factor and reschedule next polling
            currentDelayFactor += 10;
            registerNextPoll();
        } else if (event.type === 'focus') {
            // Reset delay factor and start polling if neccessary
            userActivityHandler();
        }
    }
    
    // Actually poll data
    function poll(forced) {
        // Skip polling if an ajax request is already running, unless forced
        if (!forced && ajaxRequest) {
            registerNextPoll();
            return false;
        }
    
        // If forced, abort potential current ajax request
        if (ajaxRequest) {
            ajaxRequest.abort();
            ajaxRequest = null;
        }
        // Abort potentially scheduled polling
        window.clearTimeout(timeout);
    
        // Store current timestamp
        dateOfLastCall = +new Date();
    
        // Prepare variables
        var url = STUDIP.ABSOLUTE_URI_STUDIP + 'dispatch.php/jsupdater/get',
            page = window.location.href.replace(STUDIP.ABSOLUTE_URI_STUDIP, '');
    
        // Actual poll request, uses promises
        ajaxRequest = $.ajax(url, {
            data: {
                page: page,
                page_info: collectData(),
                server_timestamp: serverTimestamp
            },
            type: 'POST',
            dataType: 'json',
            timeout: 5000
        })
            .done(function(json) {
                process(json);
            })
            .fail(function(jqXHR, textStatus, errorThrown) {
                resetJSONMemory({
                    text: textStatus,
                    error: errorThrown
                });
            })
            .always(function() {
                ajaxRequest = null;
                lastAjaxDuration = +new Date() - dateOfLastCall;
    
                // If logged out
                if (arguments.length === 3 && arguments[1] === 'error' && arguments[0].status === 403) {
                    // Stop updater
                    JSUpdater.stop();
    
                    // Present appropriate message in dialog
                    var message = $gettext('Bitte laden Sie die Seite neu, um fortzufahren'),
                        buttons = {};
                    buttons[$gettext('Neu laden')] = function() {
                        location.reload();
                    };
                    buttons[$gettext('Schließen')] = function() {
                        $(this).dialog('close');
                    };
    
                    Dialog.show(
                        $('<div>')
                            .html(message)
                            .css({
                                textAlign: 'center',
                                padding: '2em 0'
                            }),
                        {
                            buttons: buttons,
                            size: 'auto',
                            title: $gettext('Sie sind nicht mehr im System angemeldet.')
                        });
                } else {
                    registerNextPoll();
                }
            });
    }
    
    // Register global object
    const JSUpdater = {
        // Starts the updater, also registers the activity handlers
        start() {
            if (!active) {
                $(document).on('mousemove', userActivityHandler);
                $(window).on('blur focus', windowActivityHandler);
                registerNextPoll();
            }
            active = true;
        },
    
        // Stops the updater, also unregisters the activity handlers
        stop() {
            if (active) {
                $(document).off('mousemove', userActivityHandler);
                $(window).off('blur focus', windowActivityHandler);
                if (ajaxRequest) {
                    ajaxRequest.abort();
                    ajaxRequest = null;
                }
                window.clearTimeout(timeout);
            }
            active = false;
        },
    
        // Registers a new handler by an index, a callback and an optional data
        // object or function
        register(index, callback, data = null, interval = 0) {
            registeredHandlers[index] = { callback, data, interval };
        },
    
        // Unregisters/removes a previously registered handler
        unregister(index) {
            delete registeredHandlers[index];
        }
    }
    
    export default JSUpdater;