PWA: how to refresh content every time the app is opened - refresh

I created a PWA app which sends API call to my domotic server and prints the response on the home page (e.g. outside temperature and vacuum robot status).
While all the data get refreshed at very first app opening, if I minimize the app whithout completely shutting it off I have no data refreshing at all.
I was wondering how to force a refresh every time the app gets re-opened without having to do it manually (no pull-down to refresh, no refresh-button).

Found myself the solution adding the following code in service worker:
self.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'visible') {
console.log('APP resumed');
window.location.reload();
}
});

Here is the solution that works.
You can place this code wherever you have access to the window object:
window.addEventListener("visibilitychange", function () {
console.log("Visibility changed");
if (document.visibilityState === "visible") {
console.log("APP resumed");
window.location.reload();
}
});
Consider this may affect user experience or data loss with a forced reload every time the user swipes between apps.

Related

CloudKit Dashboard: Deploy Schema to Production fails with "There was a problem loading the environment’s status"

Note: This is not new, but I have some new insights on it.
For about three weeks now I regularly try to deploy the development-schema of my CloudKit Container to production, using the CloudKit Dashboard:
It spins for exactly a minute to then tell me "There was a problem loading the environment's status"
This is not new, many other questions face this as well:
Error CloudKit Dashboard - There was a problem loading the environment's status
Does iCloud need to be in the Production environment in order to use in Production?
iCloud dashboard: Cannot deploy CloudKit schema to Production
Apple support told me to
look at https://developer.apple.com/forums/thread/656723 (try again after a day with stable network)
use Safari and resetting browser settings to clear cache and cookies
"You may also try creating a new CloudKit container, rebuilding your schema, and then try again." => obviously doesn't work, because users have data on production
TL;DR:
Kill the timeout by running this in the console:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
(the response is undefined — that's okay)
How I got there
So I started to look at the requests the site makes to the backend when I click "deploy". Chrome shows that the request to
https://p39-ckdatabasews.icloud.apple.com/r/v3/user/<container-name>/production/public/admin/deployment/status?team_id=<team-id>
is cancelled after 1.0 min.
Insight 1
The problem is with the production schema. I had used the Reset Development Environment before to make sure I hadn't messed that up myself, but this would have spared me that.
I used the Copy as cURL command (in Chrome, because it also copies the auth cookies, which Safari does not) and ran it in Terminal.
Interestingly, that does respond after 1'37 min. That's also what the X-Apple-Edge-Response-Time: 97244 header says.
If you know what to look for, the console will also tell you the the request timed out:
Insight 2
The server takes too long to respond (> 1min) and the client script times out (at 1 min)
Note: You can also get a response by right-clicking the request in Chrome and choosing "Replay XHR".
Solution
I tried to understand the JavaScript that sends the XHR request and modify the timeout, but I failed. However, you can apparently clear all timeouts that exist with
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id); // will do nothing if no timeout with id is present
}
(from https://stackoverflow.com/a/8860203)
Running that while waiting for the response actually worked for me!

Apollo GraphQL unsubscribe seems to be broken

We are using Apollo GraphQL with subscriptions (via websockets) in a node.js backend and a react frontend.
The app provides a list of devices. When a user clicks on one device he gets the monitoring data for the device with live updates (from the subscription). When the user clicks on another device the subscription is stoppen, the data for the next device is being loaded and subscribed.
I pasted the messages from the websocket connection below. I first tried to paste the raw log here, but the screenshot is much easier to read.
Please ignore the ids 1-5. Important for my problem is id 6 and 7. The id is created when clicking on the first device (at 11:15:35) and then the details are closed so the subscription is stopped (at 11:15:36). Now the user clicks another device and starts subscription 7. Some seconds later the system pushes data for both, the 6th and 7th subscription.
Is there something I can do so "stop" actually means "stop" or is this a bug?
Edit: as requested, here is the code I use to subscribe/unsubscribe (I had to cut some parts due to company regulations)
const subscription = useRef(null)
const { loading, data, error, subscribeToMore } = useQuery(getDevice, { variables: { deviceId } })
useEffect(() => {
return () => {
if (!subscription.current) return
subscription.current()
subscription.current = null
}
}, [deviceId])
if (!subscription.current) {
subscription.current = subscribeToMore({
document: geDeviceSubscription,
variables: {
deviceId
},
updateQuery: (prev, { subscriptionData }) => ({ device: subscriptionData.data.subscribeDevice })
})
}
Edit 2: It is for sure not my clients issue as it also happens if the use the GraphiQL gui, start a subscription and stop it again. The new data is not displayed but it is visible in the websocket connection in the network tab of the browser (chrome).
It seems to have been a bug in an older apollo graphql or nestjs-apollo-graphql version (We use those frameworks in the backend). After upgrading all the backend dependencies to "latest", the bug doesn't seem to persist.

How to stop refreshing page on event

I'm thinking about script which refreshes browsers (chrome) page every few seconds (we can find many add-on on internet which do just that) but the script also stops refreshing page when browser senses incoming call (via WebRTC) and box is displayed in browsers corner (box to answer call). How to handle such event and stop refreshing page then?
Here is simple javascript code to refresh every ten minutes:
<script type="text/javascript">
var timeout = setTimeout("location.reload(true);",600000);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout("location.reload(true);",1200000);
}
</script>
I'm thinking about workaround.
How can i do that if i click specific button on page to refresh after 20 minutes (function resetTimeout) (let's say calls wont be longer) and after 20 minutes to refresh again every 10 minutes?
How to incorporate this script to browser for particular webpage?
Ok, i installed chrome injector and for particular page I need to write simple script like this:
var timeout = setTimeout("location.reload(true);",10000);
function resetTimeout() {
clearTimeout(timeout);
timeout = setTimeout(10000000);
}
function resetTimeout2() {
clearTimeout(timeout);
timeout = setTimeout(10000);
}
$('.button.animated.fadeIn.btn.btn-sm.btn-primary.pull-left.call').click(resetTimeout());
$('.button.animated.fadeIn.btn.btn-sm.btn-danger.pull-left.disabled.hangup').click(resetTimeout2());
Refresh page every 6000000ms. If pressed answer then refresh every 10000000ms. If pressed hangup refresh again every 6000000ms. I just need help with syntax with javascript.
when i pressed left.call button resetTimout() do not work, it still refreshes page immediately.
button.animated.fadeIn.btn.btn-sm.btn-primary.pull-left.call and the other one is Button Class element

Web worker not throws error after creation in sharepoint 2013

I can't understand whether there's something in sharepoint that that's causing
my web worker to throw an error as soon as its created In IE11 . The same worker runs great on chrome. Even tried a simple test:
the worker file :
self.addEventListener('message',function(e){ console.log("message"); })
and I'm creating the worker like so:
var worker = new Worker('http://{rootSite}/sites/53/Style%20Library/testworker.js')
worker.addEventListener('message',function(e){ console.log("message"); });
worker.addEventListener('error',function(e){ console.log("error"); });
It's strange because I tested the same script on a non sharepoint site and it worked on IE.
but on a sharepoint site as soon as create the test worker from the same site's doc library.. it throws an error.. with a null message !!
Please can anyone tell me what is going on here?!
Old question but I'd like to leave an answer for anyone who stumbles upon it.
Loading a Web worker via blob in IE has many limitations. Wouldn't recommend going down that route.
For some reason, Internet Explorer blocks Web workers from loading when the file is loaded from a sharepoint site.
Storing your Web worker files in the _layouts folder works well.
Okay ... So for all the share point developers who ever want to use web workers in their apps..
I still don't know why in internet explorer the web worker failed to load the external script
But apparently an inline web worker works !
So you could store you worker code in the doc library as a text file. And then get its content via ajax and then create an inline worker. You will need the window.URL object and the blob constructor :
First build a blob from the javascript code as a string:
Var string = "worker code ";
Var blob = new blob([ string] , {type:"text/javascript"});
Var worker = new Worker(URL.createUriObject(blob));

On server processing

I have a web application that will be doing some processing with submitted data. Instead of making the user wait for what will take at least a few seconds, maybe up to a few minutes during heavy load, I would like to know if there is some way to, within coldfusion, have processing that just occurs on the server.
Basically, the data would be passed to the server, and then the user would be redirected back to the main page to allow them to do other things, but not necessarily be able to see the results right away. Meanwhile, the processing of the data would take place on the server, and be entered into the database when complete.
Is this even possible within coldfusion, or would I need to look into using code that would receive the data and process it as a separate program?
ColdFusion 8 introduced the cfthread tag which may assist you.
<cfthread
required
name="thread name"
optional
action="run"
priority="NORMAL|HIGH|LOW"
zero or more application-specific attributes>
Thread code
</cfthread>
To do this reliably, you can use a database table as a job queue. So you when the user submits the data you insert record into the database indicating there is some work to be done. Then you create a scheduled task in the CF Administrator that polls a script that gets the next job from the queue and does the processing you describe. When complete it can update the database and you can then alert your user that there job is complete.
Make sense?
Another option that will possibly work for you is to use AJAX to post the data to the server. This is a pretty easy method to use, since you can use pretty much the exact same CF code that you have now and instead only need to modify the form submitting page (and you could even use some unobtrusive javascript techniques to have this degrade gracefully if javascript isn't present).
Here's an example using jQuery and BlockUI that will work for unobtrusively-submitting any form on your page in a background thread:
<script>
$(function () {
$("form").on("submit", function (e) {
var f = $(this);
e.preventDefault();
$.ajax({
method: f.attr("method"),
url: f.attr("action"),
data: f.serialize(),
beforeSend(jqXHR, settings) {
f.blockUI({message: "Loading..."});
},
complete(jqXHR, textStatus) {
f.unblockUI();
},
success: function (data, textStatus, jqXHR) {
// do something useful with the response
},
error: function(jqXHR, textStatus, errorThrown) {
// report the error
}
});
});
});
</script>
You should combine all three of these answers to give yourself a complete solution.
Use CF Thread to "kick off" the work.
Add a record to the DB to tell you the process is underway.
Use Ajax to check the DB record to see if the work is complete. When
your thread completes update the record - Ajax finds the work
complete and you display some message or indicator on the user's
screen so they can go on to step 2 or whatever. So each of these
answers holds a clue to a complete solution.
Not sure if this should be an answer or a comment (since I'm not adding anything new here).
We use an CF event gateway for this. The user submits a file via a web form and the event gateway monitors that upload directory. Based upon the file name the gateway knows how it should process the file into the database. This way the only real delay the user faces is the time for the file to actually transmit from their machine up to the server. We however have no need to inform the user of any statuses related to the process though could easily see how to work that into things if we did.