0 votes
by (160 points)
Hi, I was wondering if I can somehow tell the alert macro in Harlowe to be just fired once per session. I'd like to avoid it being re-fired after an Undo action.

Thanks

1 Answer

+1 vote
by (63.1k points)

Here's a function:

window.alertOnce = window.alertOnce || function (msg) {
    
    try {
        if (window.sessionStorage) {
            var store = window.sessionStorage;
        }
        
        if (store.getItem('twine-alert-flag') !== 'true') {
            alert(msg);
            store.setItem('twine-alert-flag', 'true');
        }
        
    } catch (ex) {
        console.error(ex);
        alert(msg); // alert anyway
    }
};

Usage:

<script>alertOnce('Hello world!');</script>

--or--

(set: _dummy to alertOnce('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'))

This function relies on session storage.  If session storage is shut off or unavailable, the alert will happen on undo actions like normal.  Session storage will be reset on browser restarts.

by (160 points)

Thanks a lot. it works for me. I got a couple of questions:

  • would this work for the prompt macro too
  • how would I need to adapt your function, by just replacing 'twine-alert-flag' with 'twine-prompt-flag'
by (63.1k points)
edited by

You'll need to do a bit more than that.  Here's the code:

window.promptOnce = window.promptOnce || function (msg, def) { // we need two args now for prompt
    var ret; // we need a return variable
    try {
        if (window.sessionStorage) {
            var store = window.sessionStorage;
        }
        if (store.getItem('twine-prompt-flag') !== 'true') { 
            // change the flag's name to not step on `alertOnce()`
            ret = prompt(msg, def);
            store.setItem('twine-prompt-flag', 'true');
        }
    } catch (ex) {
        console.error(ex);
        ret = prompt(msg, def); // prompt anyway
    } finally {
        ret = (ret) || ''; // harlowe flips out if the user cancels the prompt, this should fix that
        return ret; // return the input from the prompt
    }
};

Usage:

(set: $var to promptOnce('Please enter your name:', 'Luke Skywalker'))

I detailed the changes I made in comments, so maybe that'll give you a little bit of insight if you're interested.

by (160 points)
edited by

Excellent, thanks a lot. I just got one question though. can't I use name instead of ret or var. I use $name several times in other passages.
Also I figured out that if I go back (undo) I loose the $name content

PS: thanks for the comments helps a lot to understand what's going on.

by (63.1k points)
You can name variables whatever you want, but if you mean you want the prompt result in a variable called $name, just change the $var to it (or whatever you need) in the (set:). Changing the other variable names will not have any effect on anything, provided you change each one to the same thing across the code.
by (160 points)
OK, I understood this. But I'm still struggling with keeping the variable, $name in my case, persistent. If I go back (undo:) it returns `0`
...