Push Notifications. How to know if the app was in foreground or background - ibm-mobilefirst

When a notification arrives the app executes the callback configured for receiving the notifications.
In case the notification arrives with the app in background I want the application to move to a specific view. But if the notification arrives with the app in foreground I just want to print an alert.
How can I know in the callback function the status of the application when the notification arrived?
Thank you.

I don't know how dependable this is, but it seems to work when the app is running, but just in the background:
var sleeping = false;
document.addEventListener("pause", function() {sleeping = true;}, false);
document.addEventListener("resume", function() {sleeping = false;}, false);
and then:
function pushNotificationReceived(props, payload) {
if (sleeping) {
alert("caught me napping");
} else {
alert("I've been waiting for you.");
}
}
The tricky case is when the application is completely stopped. You need to log in before the notification callback gets called, and the resume event is fired long before this. If you want to handle that case, you will probably need something like the following in your WL.Client.Push.onReadyToSubscribe function:
sleeping = true;
setTimeout(function(){sleeping = false;}, 1000);
(anything that arrives within 1 second of being ready to subscribe, probably arrived when we were asleep, and is just getting delivered now)
It is a bit of a haCk, and I'm sure there are all sorts of odd timing cases but it seems to cover many of the cases.

Related

How to remove a specific notification forever using react-native-push-notification

I am currently using the react-native-push-notification library to schedule and receive notifications in my React Native app. I am able to cancel a scheduled notification using the cancelLocalNotification method, but this only cancels the notification for 24 hours. I want to find a way to remove a specific notification forever, so it will not be rescheduled.
I have tried using the following code to cancel a notification by its ID, but it only cancels it for 24 hours:
const onCancelNotification = async (id: string) => {
// Get a list of all scheduled notifications
PushNotification.getScheduledLocalNotifications((notifications) => {
// Iterate through the list of notifications
notifications.forEach((notification) => {
// Check if the notification is the one you want to cancel
if (notification.id.indexOf(id) === 0) {
// Cancel the notification
PushNotification.cancelLocalNotification(notification.id);
}
});
});
};
I would greatly appreciate any help or suggestions on how to achieve this.
This code snippet demonstrates a workaround for removing a specific scheduled local notification in React Native. The function onRemoveNotification takes in an id parameter, which is used to identify the specific notification that needs to be removed.
It's important to note that there is no direct method for removing a specific scheduled local notification in React Native. This code provides a workaround that can be used, but it's important to be aware that it relies on scheduling a notification with an earlier date and setting the repeatType to undefined.
Please note that this code is not a perfect solution and could have side effects on the app.
const onRemoveNotification = async (id: string) => {
// Get a list of all scheduled notifications
PushNotification.getScheduledLocalNotifications((notifications) => {
// Iterate through the list of notifications
notifications.forEach((notification) => {
// Check if the notification is the one you want to cancel
if (notification.data.notificationId?.indexOf(id) === 0) {
// Create a new date one day earlier than the current scheduled date
const earlyDate = moment(notification.date).add(-1, "day").toDate();
// remove the notification
// schedule the notification with an earlier date and repeat type undefined
// this will effectively "remove" the notification
// since it will not be displayed
PushNotification.localNotificationSchedule({
id: notification.id,
title: notification.title,
message: notification.message,
repeatType: undefined,
date: earlyDate,
});
// cancel the previous scheduled notification
PushNotification.cancelLocalNotification(notification.id);
}
});
});
};

WebRTC - RTCPeerConnection.onconnectionstatechange fires with RTCPeerConnection.connectionState = 'disconnected' without any reason

I am working on the WebRTC application for video chatting. On my local network everything works well. But when I try it to test through internet RTCPeerConnection.onconnectionstatechange fires with RTCPeerConnection.connectionState = 'disconnected' without any reason after some 20-30 seconds of communication. Another very confusing thing is that for example I have peer2 and peer3 started in the same browser in different tabs connected to peer1 and peer1 videostreaming to them. And after 20-30 seconds RTCPeerConnection.connectionState = 'disconnected' can fire on peer2 and at the same time peer3 continues to receive video stream from peer1. I have googled a bit and found this solution (which doesnt work in my case):
this.myRTCMediaMediatorConnections[id][hash].onconnectionstatechange=async function(e){
log('onSignalingServerMediaMediatorOfferFunc.myRTCMediaMediatorConnections['+id+']['+hash+'].onconnectionstatechange('+This.myRTCMediaMediatorConnections[id][hash].connectionState+')',10,true)
switch(This.myRTCMediaMediatorConnections[id][hash].connectionState){
case "failed":
This.disconnectMeFromMediatorConnection(targetId,logicGroupName,streamerId,streamerHash,id,hash)
break
case "closed":
This.disconnectMeFromMediatorConnection(targetId,logicGroupName,streamerId,streamerHash,id,hash)
break
case "disconnected":
if(await This.confirmPeerDisconnection(This.myRTCMediaMediatorConnections[id][hash]))This.disconnectMeFromConnection(targetId,logicGroupName,streamerId,streamerHash,id,hash)
break
}
log('onSignalingServerMediaMediatorOfferFunc.myRTCMediaMediatorConnections['+id+']['+hash+'].onconnectionstatechange',10,false)
}
this.confirmPeerDisconnection=async function(connectionObject){
log('confirmPeerDisconnection',10,true)
var b1=await this.confirmPeerDisconnectionFunc(connectionObject);
await new Promise(resolve=>setTimeout(resolve,2000));
var b2=await this.confirmPeerDisconnectionFunc(connectionObject);
log('confirmPeerDisconnection=>'+(b2-b1),10,false)
if(b2-b1>0)return false
return true;
}
this.confirmPeerDisconnectionFunc=async function(connectionObject){
var b=0
await connectionObject.getStats(null).then(function(stats){
stats.forEach((report)=>{if(report.type=='transport')Object.keys(report).forEach((statName)=>{if(statName==='bytesReceived')b=parseInt(report[statName])})})
})
return b
}
b2-b1 always equals 0 or less than 0. Can anyone give me an advise why RTCPeerConnection.onconnectionstatechange fires and how I can get rid of this bug.
Any help appriciated!

How do you poll for a condition in Intern / Leadfoot (not browser / client side)?

I'm trying to verify that an account was created successfully, but after clicking the submit button, I need to wait until the next page has loaded and verify that the user ended up at the correct URL.
I'm using pollUntil to check the URL client side, but that results in Detected a page unload event; script execution does not work across page loads. in Safari at least. I can add a sleep, but I was wondering if there is a better way.
Questions:
How can you poll on something like this.remote.getCurrentUrl()? Basically I want to do something like this.remote.waitForCurrentUrlToEqual(...), but I'm also curious how to poll on anything from Selenium commands vs using pollUntil which executes code in the remote browser.
I'm checking to see if the user ended up at a protected URL after logging in here. Is there a better way to check this besides polling?
Best practices: do I need to make an assertion with Chai or is it even possible when I'm polling and waiting for stuff as my test? For example, in this case, I'm just trying to poll to make sure we ended up at the right URL within 30 seconds and I don't have an explicit assertion. I'm just assuming the test will fail, but it won't say why. If the best practice is to make an assertion here, how would I do it here or any time I'm using wait?
Here's an example of my code:
'create new account': function() {
return this.remote
// Hidden: populate all account details
.findByClassName('nextButton')
.click()
.end()
.then(pollUntil('return location.pathname === "/protected-page" ? true : null', [], 30000));
}
The pollUntil helper works by running an asynchronous script in the browser to check a condition, so it's not going to work across page loads (because the script disappears when a page loads). One way to poll the current remote URL would be to write a poller that would run as part of your functional test, something like (untested):
function pollUrl(remote, targetUrl, timeout) {
return function () {
var dfd = new Deferred();
var endTime = Number(new Date()) + timeout;
(function poll() {
remote.getCurrentUrl().then(function (url) {
if (url === targetUrl) {
dfd.resolve();
}
else if (Number(new Date()) < endTime) {
setTimeout(poll, 500);
}
else {
var error = new Error('timed out; final url is ' + url);
dfd.reject(error);
}
});
})();
return dfd.promise;
}
}
You could call it as:
.then(pollUrl(this.remote, '/protected-page', 30000))
When you're using something like pollUntil, there's no need (or place) to make an assertion. However, with your own polling function you could have it reject its promise with an informative error.

BusyIndicator not working

Worklight busyindicator not working properly.My isssue is i'm using multipage.On page change i call adapter for webservice and call busy indicator so that it show work in progress while fetching.but what happen is page change and indicator show and hide quickly but adpater still in fetching phase and after sometime data called successfully but during these working no busy indicator shows.
var busyIndicator = null;
function wlCommonInit(){
busyIndicator = new WL.BusyIndicator();
}
This is the code i call on page change.
busyIndicatorDemo();
var viewPath = "views/add_fund_transfer.html";
WL.Page.load(viewPath,
{
onComplete: function() {
PayAnyOne_Controller.GetBranches(GetBranchesProcedureName);
busyIndicator.hide();
}
});
function busyIndicatorDemo() {
busyIndicator.show();
setTimeout(15000);
}
its seems like busyindicator doesn't work with adpater when using in multipage.
Please give me the solution or the problem in my code.
Thanks.
It seems like the problem is in the flow of the code. you're running this code basically:
show busy indicator
load page
when page has finished loading: invoke procedure (async call), and hide busyindicator.
So this generates the behavior you've reported - the busyindicator is shown and quickly hidden once the page has finished loading, even though the service is still fetching data (in an async call)
moving the busyindicator.hide to the onSuccess of the invoke procedure should solve the problem (put it also in the onFailure ...)
Hope this helps

Sencha Touch: Prevent multiple concurrent transitions

QA just filed a real doozy of a bug, and I'm scratching my head how to fix it.
If two buttons, e.g. back, and search are pressed at the same time, each will invoke Ext.dispatch, causing two simultaneous opposing transitions! This totally !##$s up the layout, rendering the app unusable.
This is really a general problem with touch-enabled apps... with multiple fingers hovering over the screen, the user can easily trigger weird and totally incompatible action combinations, and the app needs to accept only one at a time. Is there any way to handle this situation gracefully in Sencha Touch?
I fixed it by listening to the before-dispatch event, and canceling it if there is a dispatch already in progress.
Ext.regApplication(...
this._isDispatching = false,
launch: function() {
Ext.Dispatcher.on('before-dispatch', function () {
var me;
if (this._isDispatching)
return false;
else {
this._isDispatching = true;
me = this;
setTimeout(function () {
me._isDispatching = false;
}, 500);
return true;
}
}, this);
}
Yes, the 500ms delay is definitely hacky, but I couldn't think of a more robust way of detecting when the transition has completed. There is no after-dispatch event, and the dispatch event fires before the transition has completed.
Hope this helps someone.