Onscreen notification when a table gets updated

Good afternoon. Is there a way to have notification from when a table get updated while not watching the table? I am making a messaging application and the way it work is: the user will select from a list of contacts, enter the subject and body and press send. Pic for details:


This table has been filtered to show messages TO the logged in person. Still in testing phase thats why it looks like its messaging itself. There is also a 60 sec auto logout. As I cant guarantee this person will stay on this page Im looking for a way to let them know on another page that they have a new message.

Hope all this made sense

The problem you’re going to run into is that your Table can broadcast that there has been a change, but you need something consistent to listen for that broadcast. Shared Docked Views are excellent for this (as long as they’re never overridden), but you need some piece of UI that is present on EVERY page for this to work correctly.

The general breakdown:
Whenever the Table receives new data, you want to notify all pages of a session to display a “notification”, and I suggest you’ll also probably want to remove the notification after some time.

Important pieces:
Change Script on Table.props.data
Some sort of container/component which is always present on every page.

1. Change Script for Table.props.data:

# we need to send the pageId to omit the page which contains the Table
system.perspective.sendMessage("TABLEUPDATE", payload={"pageId":self.page.props.pageId}, scope="session")

2. The TABLEUPDATE Session Message Handler, located on some sort of shared omni-present root/container/component:

	from time import sleep
	pageId = self.page.props.pageId
	if pageId != payload["pageId"]:
	    system.perspective.openPopup(id=pageId, view="Alt", position={"right": 10, "top": 10}, showCloseIcon=False, pageId=pageId)
	    sleep(5)  # adjust as desired
	    system.perspective.closePopup(id=pageId)

Idiosyncrasies to watch for:

  • If the table updates during the five seconds the popup is open, then the popup will still be closed after the original five seconds have elapsed.
2 Likes

Thank you for the idea. I am going to try it today.

How about a message handler in the session scripts ? Can’t something be done from there ?

The Session-level message handlers do not have a Perspective page thread attached to them (no page context because this is a Session event), so most system.perspective package functions will fail when executed in those handlers. The only thinsg I recommend doing within the Session-level handlers is sending a hand-off message to be hard by some part of an omni-present UI, or acting on the session object provided as part of the handler.

Im thinking I am going to make another table and populate it with a badgenum and a time stamp.

I have this as a script to poplulate that table:

	BadgeNum = '0038014279'
	LogInTime = system.date.now()
	LastLogIn = system.db.runScalarPrepQuery("SELECT 1 FROM New_Message_Alarm WHERE BadgeNum = ?", [BadgeNum], 'IgnitionMessagingUserForMessagingApp')
	if LastLogIn == 1:
		system.db.runPrepUpdate("INSERT INTO New_Message_Alarm WHERE BadgeNum = ? (LastLogIn) Values(?)",[BadgeNum, LogInTime])
	else:
		system.db.runPrepUpdate("INSERT INTO New_Message_Alarm (BadgeNum, LastLogIn) Values(?,?)",[BadgeNum, LogInTime])

It says I have incorrect syntax by the key word WHERE on the runPrepUpdate at the if statment. What am I missing?

Perhaps I am confused, but if the “table” sends a message why can’t a session message handler pick it up and open a popup to display your notification? Any running session will get this notification.

I know I have done this before, just not 100% on how I did it now.

Edit, yes I think I was sending a Page Id as part of the payload.

SQL Inserts don’t accept WHERE clauses themselves, unless you use a SELECT instead of VALUES.

Because system.perspective.openPopup() requires a page thread in order to execute, but the Session Message Handler (Project > Session Events > Message) is just operating blindly on the Gateway - with only the session object supplied.

Executing that Message Handler results in the following exception:

java.lang.IllegalArgumentException: No perspective page attached to this thread.

You could modify the code to supply the pageId argument, but you'd need to either send those as part of the payload or obtain them in the Message Handler and then omit the page with the table by passing only that page as part of the payload:

def handleMessage(session, payload):
	for sessionObj in system.perspective.getSessionInfo():
		if sessionObj["sessionScope"] != "designer":
			for pageId in sessionObj["pageIds"]:
				system.perspective.openPopup("X", "View", pageId=pageId)
def handleMessage(session, payload):
	for sessionObj in system.perspective.getSessionInfo():
		if sessionObj["sessionScope"] != "designer":
			for pageId in sessionObj["pageIds"]:
				if pageId != payload["originPageId"]:
					system.perspective.openPopup("X", "View", pageId=pageId)

Yep, you must have missed my edit to my post.

May I get an example of this? Thank you

This worked:

system.db.runPrepUpdate("UPDATE New_Message_Alarm SET LastLogIn = ? WHERE BadgeNum = ?", [LogInTime, BadgeNum])

Incase you wanna to see the final result here it is:

BadgeNum = self.session.custom.View_Keyboard
	LogInTime = system.date.now()
	LastLogIn = system.db.runScalarPrepQuery("SELECT 1 FROM New_Message_Alarm WHERE BadgeNum = ?", [BadgeNum], 'IgnitionMessagingUserForMessagingApp')	
	if LastLogIn == 1:
		LLTS = system.db.runScalarPrepQuery("SELECT LastLogIn FROM New_Message_Alarm WHERE BadgeNum = ?", [BadgeNum], 'IgnitionMessagingUserForMessagingApp') #Looks at a table to see when the last time someone logged in
		LMTS = system.db.runScalarPrepQuery("SELECT TOP 1 [Time:] FROM Message_Table WHERE [To:] = ? ORDER BY [Time:] DESC",[BadgeNum], 'IgnitionMessagingUserForMessagingApp')	#Looks at message table to see when last message was sent to that BadgeNum
		system.db.runPrepUpdate("UPDATE New_Message_Alarm SET LastLogIn = ? WHERE BadgeNum = ?", [LogInTime, BadgeNum]) #Updates LastsLogIn with timestamp
		if LLTS < LMTS: #Compares the last login timestamp to the new message timestamp
			self.getSibling("NewMessage_Label").meta.visible = True
		else:
			self.getSibling("NewMessage_Label").meta.visible = False	
	else:
		system.db.runPrepUpdate("INSERT INTO New_Message_Alarm (BadgeNum, LastLogIn) Values(?,?)",[BadgeNum, LogInTime])
1 Like