Perspective: How to delay script run to close dock in x seconds

I have a footer that I want to display for a couple seconds and then hide again, but I note that invokeLater isn’t available for Perspective, and the Timer component doesn’t exist either. I’m not sure how else to do this?

Cheers!

Make a custom property MyKey on the footer.
Bind the visible property of the footer to

dateIsBefore(now(1000),{this.custom.MyKey})

Now you can set the value of MyKey to now + 5 seconds.
self.getSibling("Label").custom.MyKey = system.date.addSeconds(system.date.now(),5)

2 Likes

Interesting idea, but setting the visible property just hides the contents of the View and doesn’t hide the View itself. I need to call the function system.perspective.closeDock('Footer').

If I could use your method with a propertyChange event handler though it would work, I just can’t find any such event handler…

Would it do what you’re looking for if instead of binding the visible property, you put that binding on a custom property, and then right-click on the custom property, select Add Change Script… and write your script there?

1 Like

Perfect! I forgot those were there, cheers. Works like a charm now thanks to both of you.

Hmm, I might have jumped the gun. My onStartup event (tried on the View as well as the root objects) doesn’t seem to be firing after it opens for the first time. It seems like the dock doesn’t actually get closed, but more it’s hidden in the background. So when I open it again, it doesn’t actually fire any of the startup events. I could pass in a parameter to the View which I could then use to force it to run the script… but it’s all feeling overly complicated for such a seemingly simple task, that I’m sure there must be a more efficient way?

You want to be careful using parameters with Docked Views, as Parameters are really meant to be used for initial construction (it just happens that in most instances a parent View has direct access to parameter values, and so in those instances they can be updated on-the-fly - Docked Views do not have that capability).

My recommendation is (surprise, surprise) to use Perspective’s sendMessage() function. Your Docked View would need to have a listener present (you can use the root)

In the Docked View listener (listening at session scope):

dockedViewId = value['dockedViewId']
pageId = value['pageId']
sessionId = value['sessionId']
if value['command'] == 'open':
    system.perspective.openDock(id=dockedViewId, pageId=pageId], sessionId=sessionId)
elif value['command'] == 'close':
    system.perspective.closeDock(id=dockedViewId, pageId=pageId], sessionId=sessionId)

You can trigger the open/close wherever you like, but it should call out to a project script:

project.myScript.manageDockedView(dockedViewId='myDockedViewId', pageId=page.props.pageId, sessionId=session.props.id, command='open')

Project Script:

def manageDockedView(command, dockedViewId, pageId, sessionId):
    system.perspective.sendMessage(messageType='MANAGEDOCKEDVIEW', payload={'command':command, 'dockId':dockedViewId, 'pageId':pageId, 'sessionId':sessionId}, scope='session')

Ok, I think I got it. In order to delay it, I would still use the now+3s part, but the message handler on the docked view would effectively trigger the dock to update the ‘close time’. I’ll give it a go when I’m back in the office, cheers!

Ah, I forgot this entire thread was about delaying the action!

What I would do is include the delay as part of the project script as an optional argument and just sleep that long before executing the rest of the script.

Ok, so literally just (excluding delay param for simplicity here):

import time
time.sleep(3)

I thought this might lock up the UI like it does in vision, but no?

No UI to lockup via scripting - all your scripts are running in a (dedicated, per-session) channel on the Gateway. The UI never actually runs your code - it’s all running via JS.

Awesome, I’ll give it a go. Thanks guys

Edit: Just tested, and now working as intended, cheers. Perspective is still extremely new to me… :no_mouth: