Servoy / webnotifications

MIT License
1 stars 2 forks source link

Close-Event-Handler #7

Closed philippr71 closed 3 years ago

philippr71 commented 4 years ago

Is it possible to add the Close-Event-Handler (maybe even all Callbacks), so we can handle the Close-Event in Servoy, when the (optional) Close-Button is clicked? This is documented under "https://github.com/CodeSeven/toastr", "Callbacks" (example: toastr.options.onCloseClick = function() { console.log('close button clicked'); })

pruhsert commented 4 years ago

That should be possible, yes. May I ask for the use case for this?

philippr71 commented 4 years ago

We're checking if the user is still active. After 10 minutes of inactivity, we're showing a notification, that the session will be closed in 30 seconds, if there will not be any action within this period. So, if the user closes this warning-notification, the inactivity-checker restarts counting down from 10 minutes (there are other ways for the user to show activity but this is one possibility).

We also tried that with plugins.dialogs, but this has the downside, that we get an error in the server-log when the session is terminated after the 30 seconds of warning dialog time.

seanthomasdevlin commented 4 years ago

Hi Philippr71,

Curious, how do you check if the user is "still active" ? Client-side with the SvyIdle Project? Or server-side with the client manager plugin ? Or something else ?

philippr71 commented 3 years ago

We start a "scheduler"-Job (plugins.scheduler) in onSolution open and restart this Job for example when a form is shown or in "onElementDataChange" (and hopefully in the future, when the toastr-message is closed ;-)

It looks like this in onSolutionOpen:

function onPortOBOpen(arg, queryParams) {

    // Bei REST-Aufrufen wird der folgende Block ignoriert!
    if (arg != "rest_ws_server") {

        scopes.omng_inactivitychecker.initIncativityChecker(600, 30, i18n.getI18NMessage("om.portob.inaktivitaet"), i18n.getI18NMessage("om.portob.inaktivitaet.meldungstext"), leaveToEndUrl);

  ....
}

and onShow (or simular onElementDataChange) looks like this:

function onShow(firstShow, event) {

    scopes.omng_inactivitychecker.updateLastActivity();

        ...
}

The Scope with the Helper-Functions (scopes.omng_inactivitychecker) looks like this:

/**
 * Diese Variable wird für den Scheduler-Job-Namen, welcher auf Inaktivität prüft, verwendet
 * 
 * @type {String}
 * 
 * @private 
 *
 * @properties={typeid:35,uuid:"8928353D-EE95-4C7C-92F8-B7568362591D"}
 */
var JOBNAME = "ch.omcomputer.inactivitychecker.jobname";

/**
 * Zeit der Inaktivität bis eine Warnung ausgegeben wird (in Sekunden)
 * 
 * @type {Number}
 * 
 * @private 
 *
 * @properties={typeid:35,uuid:"E5DDECB0-4048-4AED-9D2C-7C43BE01CE20",variableType:4}
 */
var WarningDelay = -1;

/**
 * String, welcher bei Inaktivität als Titel im Warnungsdialog ausgegeben werden soll
 * 
 * @type {String}
 * 
 * @private 
 * 
 * @properties={typeid:35,uuid:"98BBA5E4-2B38-4DBA-8A3B-BA48AF21FCD8"}
 */
var WarningTitle = null;

/**
 * String, welcher bei Inaktivität als Text im Warnungsdialog ausgegeben werden soll
 * 
 * @type {String}
 * 
 * @private 
 * 
 * @properties={typeid:35,uuid:"04286681-FD9E-46E7-9086-573F81D51090"}
 */
var WarningMessage = null;

/**
 * Zeit der Inaktivität nach Ausgabe der Warnung bis die Session endgültig beendet wird (in Sekunden)
 * 
 * @type {Number}
 * 
 * @private 
 *
 * @properties={typeid:35,uuid:"005986C1-75C5-461F-8AE7-7AC062CF8685",variableType:4}
 */
var LogoutDelay = -1;

/**
 * Referenz auf Funktion, welche für Logout verwendet werden soll (sollte Session in stabilem Zustand aufräumen)
 * 
 * @type {Function}
 * 
 * @private 
 * 
 * @properties={typeid:35,uuid:"72CB9BF2-EAF4-4280-BD62-C6689FC026FA",variableType:-4}
 */
var LogoutFunction = null;

/**
 * Initialisiert die Prüfung auf Inaktivität
 * 
 * @since  03.11.2020
 * @author Roland Philipp
 * 
 * @param {Number} [secsToWarning] Zeit in Sekunden bis Warnung angezeigt werden soll
 * @param {Number} [secsToLogout] Zeit in Sekunden nach Warnung bis Session beendet werden soll
 * @param {String} [warningTitle] Titel, welcher im Warnungsdialog angezeigt werden soll
 * @param {String} [warningText] Text, welcher im Warnungsdialog angezeigt werden soll
 * @param {Function} [logoutFunction] Referenz auf Funktion, welche zum Beenden der Session ausgeführt werden soll
 * 
 * @public 
 *
 * @properties={typeid:24,uuid:"098DD08B-0248-44B9-B2DD-F4C8BA196DE8"}
 */
function initIncativityChecker(secsToWarning, secsToLogout, warningTitle, warningText, logoutFunction) {

    // Bei einem Headless-Client darf es keine Inactivity-Prüfung geben!
    if (application.getApplicationType() != APPLICATION_TYPES.HEADLESS_CLIENT) {

        application.output("Inaktivitätsprüfer gestartet!", LOGGINGLEVEL.DEBUG);

        WarningDelay = secsToWarning ? secsToWarning : 600;
        WarningTitle = warningTitle ? warningTitle : "Inaktiv";
        WarningMessage = warningText ? warningText : "Sie werden demnächst abgemeldet!";
        LogoutDelay = secsToLogout ? secsToLogout : 30;
        LogoutFunction = logoutFunction ? logoutFunction : defaultLogoutFunction;

        updateLastActivity();
    }
}

/**
 * Entfernt den Scheduler-Job, welcher auf Inaktivität prüft
 * 
 * @since  06.11.2020
 * @author Roland Philipp
 * 
 * @return {Boolean}
 * 
 * @public 
 * 
 * @properties={typeid:24,uuid:"C8680B52-F04D-458A-A845-D5E73CB453DB"}
 */
function removeInactivityChecker() {
    return plugins.scheduler.removeJob(JOBNAME);
}

/**
 * Aktualisiert den Zeitpunkt der letzten Aktivität.
 * Diese Funktion muss von der Hauptanwendung an den geeigneten Stellen aufgerufen werden, um den Timer
 * zurückzusetzen. Siehe Anwendungsbeispiel im Bussenprotal.
 * 
 * @since  02.11.2020
 * @author Roland Philipp
 * 
 * @public 
 * 
 * @properties={typeid:24,uuid:"0E05481E-1E86-4D98-9BD2-2F10905DB7CA"}
 */
function updateLastActivity() {

    if (WarningDelay > -1) {

        removeInactivityChecker()

        plugins.webnotificationsToastr.clear();

        var warningTime = new Date().getTime() + (WarningDelay * 1000);
        plugins.scheduler.addJob(JOBNAME, new Date(warningTime), showInactivityWarning);
    }
}

/**
 * Callback-Funktion für Inaktivitäts-Prüfungs-Job (Scheduler-Job) für Anzeige einer Warnung
 * 
 * @since  02.11.2020
 * @author Roland Philipp
 * 
 * @private  
 * 
 * @properties={typeid:24,uuid:"33A48DC4-3A16-4BAB-A3F8-DC37FFD3D2B7"}
 */
function showInactivityWarning() {

    plugins.scheduler.removeJob(JOBNAME);

    var logoutTime = new Date().getTime() + (LogoutDelay * 1000);
    plugins.scheduler.addJob(JOBNAME, new Date(logoutTime), LogoutFunction);

    var options = {
        "newestOnTop": true,
        "hideEasing": "linear",
        "showMethod": "fadeIn",
        "hideMethod": "fadeOut",
        "timeOut": (LogoutDelay * 1000),
        "progressBar": true     
    }

    plugins.webnotificationsToastr.warning(WarningMessage, WarningTitle, options);
}

/**
 * Standard-Funktion zum Beenden der Session, falls nichts anderes bei der Initialisierung angegeben
 * 
 * @since  16.11.2020
 * @author Roland Philipp
 * 
 * @private 
 * 
 * @properties={typeid:24,uuid:"8A76AD0A-EB62-48DA-BC48-463C1D80A23C"}
 */
function defaultLogoutFunction() {

    application.showURL("https://www.omcomputer.ch", "_self");
    application.exit();
}
seanthomasdevlin commented 3 years ago

Hi Philippr71,

Interesting approach 😉

May I recommend the svyIdle project. It will detect this kind of activity down in the browser, so you don't have to manage it in many places.

Best, Sean

philippr71 commented 3 years ago

Hi Sean

Thanks, very good recommendation. This is really the better trigger, than the one if've created with "updateLastActivity"-Function-calls. I now just use the svyIdle to trigger if the user is idle or not.

I've done this in the "initActivityChecker" instead of "updateLastActivity" and I've removed all calls of "updateLastActivity" (in onShow etc) The rest stays the same. Works perfect for me.

Best, Roland

seanthomasdevlin commented 3 years ago

Hi Roland,

Excellent to hear that it's working for you. I will close this ticket then if the use case is better solved by SvyIdle. Thanks for using Servoy's extensions and for posting your feedback.

Best, Sean