Hey all,
Stumbled on the same issue some time ago. We had dashboards running 24/7 on floors with no user access (only screen) or seldom user interaction so their versions always got stuck and had to be manually refreshed.
The most obvious path was to create a "ping" table and set the app_uuid
and version_number
I wanted to lock in and all open apps would poll that every 10 minutes. If the specified version was higher then the current version I would issue a page refresh.
The problem was, multiple tabs, multiple machines, same user. I needed a simple heuristic for grouping devices by browser and platform. That would catch at least most of the cases.
const browserName = navigator.userAgent.match(/(Firefox|Chrome|Safari|Opera|MSIE|Trident|Edge)\/?\s*([\d\.]+)/i)?.[1].toLowerCase() || '';
const platformName = navigator.userAgent.match(/(Macintosh|Windows|Linux)/i)?.[0].toLowerCase() || '';
return `${platformName}_${browserName}`.replace(/\s/g, '');
Add the tables:
- marco
- polo
- marco_id
- user_email
- device_fingerprint
The periodically executed marco query which fetches new "pings" and evaluates if a refresh is necessary.
SELECT
m.id AS marco_id,
m.app_version,
m.app_uuid,
(
(LPAD(REPLACE(m.app_version, '.', ''), 3, '0')::INT > LPAD(REPLACE({{app_version_simulator.value}}, '.', ''), 3, '0')::INT)
AND p.id IS NULL
)AS should_reload,
LPAD(REPLACE(m.app_version, '.', ''), 3, '0')::INT AS lh_vsum,
LPAD(REPLACE({{app_version_simulator.value}}, '.', ''), 3, '0')::INT AS app_vsum,
p.id AS polo_id,
p.user_email,
p.device_fingerprint
FROM
marcos AS m
LEFT JOIN polos AS p ON (
p.marco_id = m.id
AND (
p.user_email = {{current_user.email}}
OR p.user_email IS NULL
)
AND (
p.device_fingerprint = {{device_fingerprint.value}}
OR p.device_fingerprint IS NULL
)
)
WHERE
m.app_uuid = {{retoolContext.appUuid}}
ORDER BY
lh_vsum DESC
LIMIT
1
The logic of the above query boils down to these two fields which are included in the response:
{
"app_version": "0.1.1",
"should_reload": true,
}
A success handler executes the "polo" query (if the current app version is less then the marco app version) which just adds a record against the "marco" record noting down the user_email
and device_fingerprint
. Once saved:
utils.showNotification({
title: "Refreshing the app in 10 seconds",
})
await new Promise(resolve => setTimeout(resolve, 10000))
utils.openUrl(urlparams.href, {newTab: false, forceReload: true})
That's a tl;dr of how I implemented it. I can create a demo app if anyone is interested 