Which event triggered at start of Fiori app? - events

I'm trying to create a FLP plugin which executes and does some checks before and a will be opened from the launchpad. If those checks fail the app shouldn't start up and instead it should display a dialog which informs the user that the application isn't available right now.
So the creation and configuration of the FLP plugin was successful. But now I'm stuck because I don't know which event I need to listen to. While searching through the internet I found these to approaches:
return Component.extend("ch.srgssr.zcaflpmntchk.Component", {
...
init: function () {
...
sap.ui.getCore().getEventBus().subscribe(
"sap.ushell",
"appOpened",
(e1, e2, appMeta, e4) => console.log("onAppOpened", {e1, e2, appMeta, e4}),
this
);
return Component.extend("ch.srgssr.zcaflpmntchk.Component", {
...
init: function () {
...
sap.ushell.Container.getService("AppLifeCycle").attachAppLoaded(() => console.log("attachAppLoaded"));
Unfortunately both events are fired after the app is loaded and no matter what I do (or throw) I can't stop loading the app once the event is fired.
So on which event do I need to listen to be able the stop loading the app? Is there a "beforeAppLoaded" or something? Can't find a proper list of available events. I'm looking through several code examples and taking possible solutions from there.

Related

MacOS not responding to MPRemoteCommandCenter commands in the background

I am writing an application for my own purposes that aims to get play pause events no matter what is going on in the system. I have gotten this much working
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.togglePlayPauseCommand.isEnabled = true
commandCenter.togglePlayPauseCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("Play Pause Command")
return .success
}
commandCenter.nextTrackCommand.isEnabled = true
commandCenter.nextTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("NextTrackCommand")
return .success
}
commandCenter.previousTrackCommand.isEnabled = true
commandCenter.previousTrackCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("previousTrackCommand")
return .success
}
commandCenter.playCommand.isEnabled = true
commandCenter.playCommand.addTarget { (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus in
print("playCommand")
return .success
}
MPNowPlayingInfoCenter.default().playbackState = .playing
Most of those methods are there because apparently you will not get any notifications without having nextTrackCommand or previousTrackCommand or playCommand implemented.
Anyways my one issue is that as soon as you open another application that uses audio these event handlers stop getting called and I cant find a way to detect and fix this.
I would normally try doing AVAudioSession things to state this as a background application however that does not seem to work. Any ideas on how I can get playpause events no matter what state the system is in?
I would like to be able to always listen for these events OR get an indication of when someone else has taken control of the audio? Perhaps even be able to re-subscribe to these play pause events.
There's an internal queue in the system which contains all the audio event subscribers. Other applications get on top of it when you start using them.
I would like to be able to always listen for these events
There's no API for that but there's a dirty workaround. If I understand your issue correctly, this snippet:
MPNowPlayingInfoCenter.default().playbackState = .paused
MPNowPlayingInfoCenter.default().playbackState = .playing
must do the trick for you if you run it in a loop somewhere in your application.
Note that this is not 100% reliable because:
If an event is generated before two subsequent playbackState state changes right after you've switched to a different application, it would still be catched by the application in the active window;
If another application is doing the same thing, there would be a constant race condition in the queue, with unpredictable outcome.
References:
Documentation for playbackState is here;
See also a similar question;
See also a bug report for mpv with a similar
issue (a pre-MPRemoteCommandCenter one, but still very valuable)
OR get an indication of when someone else has taken control of the audio
As far as I know there's no public API for this in macOS.

Google Publisher Tag, how to remove event listener from Service

There seem to be several questions on how to register events to a gpt service:
Google Publisher Tag registering to Events
registering to events with google publisher tag
How to do this is clearly defined in the documentation:
googletag.pubads().addEventListener('eventName', callbackFn);
I add my event to the service when the component (React) mounts inside the callback function of window.googletag.cmd.push as described in this tutorial by Google.
Now the problem is that every time I change page, more event listeners are added to the service. I can make sure only one event listener executes on the actually existing slots by using this method (from the documentation):
googletag.pubads().addEventListener('impressionViewable', function(event) {
if (event.slot == targetSlot) { // will only run on target slot
// Slot specific logic.
}
});
But more an more event listeners will remain active and keep on executing (without executing the code within the if-statement).
Now, I assumed google would have implemented something like this (to run on componentWillUnmount):
googletag.pubads().removeEventListener('eventName', callbackFn);
But it doesn't exist in the documentation and I can't seem to find any way to remove active event listeners from the service?
So I went with this:
let eventListnerCreated = false;
if(!eventListnerCreated) {
eventListnerCreated = googletag.pubads().addEventListener("slotRenderEnded", function(event) {
// blablabla
});
}
Not clean. But will work.
I know this doesn't solve the original issue of removing the event listener, but this will let's not create event listeners again and again.

Angular 6 : is there any chance of performance issue when using #HostListener?

I've an angular app , I want to automatically from the application if the user put the browser idle for a long period of time . Say 15 minutes . For that ive written a service and its working fine . I'm catching user action using #HostListener . But I feel like , there might be a chance for a performance issue as the HostListener method is called upon each user action .
#HostListener('document:keyup', ['$event'])
keyUpListenere(event) {
this.idleTimeoutService.resetTimer();
}
#HostListener('document:click', ['$event'])
clickListener() {
this.idleTimeoutService.resetTimer();
}
#HostListener('document:wheel', ['$event'])
mouseWheelListener () {
this.idleTimeoutService.resetTimer();
}
Not at all, many applications use this kind of thing for automatic popup remiders of session timeouts. I would also include touchstart and/or touchend.
Yes, there are chance of performance, think that you are creating 3 listener that listen the actions on all your document.
You can assign this events on a main div of app.component on event functions, is better than make listeners.

Open Sockjs inside an application

I want to create an application where on page3 users start communicating via a sockjs websocket (they go through page1 and page2 to reach page 3). The code is working fine but I dont know why!
// Global scope
var sock;
// Inside a function page3, this is invoked when Page3 loads for the first time
function page3(){
// Local scope
sock= new SockJS("localhost:8080/messages);
sock.onopen= function(){
....
};
sock.onmessage= function(data){
....
};
}
My question is - when a message is sent from the server how is sock.onmessage accessed by program execution even though it is 'seen' only when Page3 is loaded the first time which is when function page3() is called?
Looks like sock is not imported (the error message is saying that it is whats undefined)
Perhaps if you could share more of the code we could see why
Found my own answer.
The question is actually related to visibility of event listeners on the client. And the answer to that is - all event listeners on the client, once activated (flow of program execution having "seen" them) remain active until they are removed.
So in the above case, even though function page3() was "seen" by program execution only once - when Page3 was loaded for the first time, sock.onmessage becomes activated as a (client) event listener during that page3() function call and continues to remain active until the socket is closed.
As such, there is no need for an explicit page3() function call to trigger sock.onmessage. It (sock.onmessage) will keep listening to socket events sent by the server.

In an acceptance test, how do I know when my asynchronous events are?

So here's the rub - I have a system that, when an event occurs, fires off a chain of disparate asynchronous code (some code even fires off more events).
Now during acceptance testing I fire that same event - but what strategy should use to notify the test runner that all the subsequent events are finished and ready to move on to the next step?
I started out just waiting for fixed amount of time - but I that was always just a fudge.
And now, I'm hooking in to the tail events and moving on when they have all finished. But I can see this becoming v. complex as the system grows.
Just wondering if there is an alternative strategy that I've missed. Any suggestions?
FWIW I'm using cucumber.js & zombie to test an express app on node.js.
Cheers and thanks for your time,
Gordon
Obviously, the solution will be different depending on the application, but I find it helpful to architecture my applications in such a way that callbacks for the top-level asynchronous functions are tracked all the way to the end. Once all the top-level callbacks are done, you can fire some event or call some callback that indicates everything is over. Using something like async's parallel, you could potentially do something like this:
eventEmitter.on('someEvent', function(some, data, callback) {
async.parallel([
function(cb) { firstAsyncThing(some, cb); },
function(cb) { secondAsyncThing(data, cb); }
], function(err, results) {
// called when all functions passed in the array have their `cb` called
callback(err, results);
});
});
So then you can pass a callback into your event:
eventEmitter.emit('someEvent', 'some', 'data', function(error, results) {
// the event has been fully handled
});

Resources