Chromecast event for device disconnect (sender) - google-chrome

Is there event that will notify a sender app when the use selects "stop cast" from within the chrome extension?
I've a chrome sender app get's in a limbo state if the user chooses to stop the cast from the extension instead of the app cast button.
EDIT:
This is some relevant code:
CastPlayer.prototype.onMediaDiscovered = function (how, mediaSession) {
this.currentMediaSession = mediaSession;
// ...
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
// ...
};
CastPlayer.prototype.onMediaStatusUpdate = function (e) {
console.log(e);
};

Have you tried Session.addUpdateListener(listener) ? I think the listener will be notified when the session is no longer alive.

It seems Google developers are pretty aware of that! :D
They've just update their senders sample code with a commit that is exactly what seems you're looking for: Added session update listener to handle disconnect by clicking cast extension
There's also another commit with the same text in another sample but with less code, here you have: https://github.com/googlecast/CastHelloVideo-chrome/commit/776559c9aaf16d7d82c62ee4dea611b6177ac217

Related

Infinite Redirect Loop on Google One Tap Signin

I'm having trouble finding any documentation in regards to Google One Tap UX and how to persist signin state after a signin redirect. I am using the html api, check the code here:
setTimeout(function () {
let target = document.getElementById('google-signin');
target.innerHTML = '<div id="g_id_onload" data-client_id="x" data-context="signin" data-login_uri="https://x/account/google/callback" data-auto_select="true" data-itp_support="true"></div>';
var s = document.createElement("script");
s.src = 'https://accounts.google.com/gsi/client';
document.head.appendChild(s);
console.log('appended script', s);
}, 30000);
</script>
Essentially I am delaying this signin popup for 30 seconds, that part works fine but soon after this is what happens:
Sign in occurs
Redirect happens
Server redirects back to the referer page
After 30 seconds the process starts again
I would have assumed the google sdk would set a cookie or something somewhere but I guess it does not, either that I'm supposed to handle persisting signin state through my own means. I just want to know the correct approach here.
My question is: How does google know if a user has already signed in using Google One Tap UX?
Figured out a solution. Google allows you to put a property on your div tag called data-skip_prompt_cookie="yourcookie" this will skip the one tap prompt if that cookie is present with a truthy value.
What I did was on my server callback in asp.net I added a cookie to the response. This ensures the prompt is only disabled once someone actually signs in.
Response.Cookies.Append(
"yourcookie", "true");
This ensures when my server redirects back to the originating page, the cookie exists and the one tap does not show up again

PWA: How to retrigger beforeinstallprompt?

Our site uses PWA so that the visitor can choose to Add to Home Screen (A2HS). However, from Google Analytics data, the Dismiss rate is too high compared to Acceptance rate.
We plan to make the UX more intuitive and clearer to improve the acceptance rate. However, we also want to revive those visitors already dismissed the A2HS dialog.
How to do so? To the extend of my knowledge, we only can add beforeinstallprompt listener but there is no openinstallprompt method.
For security reasons, as others have written as well, browsers don't allow you to manually trigger the install event.
However, there is a way you can test it yourself. Go to chrome://flags and enable "Bypass user engagement checks"
This will kick off the prompt so you can test.
Cheers
No, You can't trigger the install banner and its driven by the browsers. If your site meets all PWA criteria and if the user is visiting frequent enough(how frequent enough is not explicitly stated by browser vendors), browsers will show the prompt again. We can't trigger the same with our code. Refer this answer on why it behaves that way and whats the alternate solution.
Anand's answer is correct for now. But starting Chrome 68, Chrome will not automatically show the A2HS prompt. You will need to explicitly tell Chrome to trigger the prompt.
According to Google's documentation, here is the snippet of code to handle the prompt;
Listen for the beforeinstallprompt
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
});
Insert the following code in a listener that will trigger the prompt
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
Refer this link for further information.
In Dev mode,
Try this in devtools(tried in chrome) console to trigger the event:
event = new Event('beforeinstallprompt')
window.dispatchEvent(event)
Caution: We won't be able to open the in-browser modal by calling prompt on the event.

What's the replacement for history's useBeforeUnload to show a confirmation dialog in react-router?

In the example here and in this issue comment it is suggested to use the useBeforeUnload function of history.
However, this function is gone. It seems to be removed without replacement in the current 4.x version:
Removed the "middleware" API (i.e. all "use" functions).
What's a good way to handle catch these "before unload" cases now in order to show a confirmation dialog?
Taking a look at the code for history's createBrowserHistory, it looks like the block function does what you need. From the docs:
// Register a simple prompt message that will be shown the
// user before they navigate away from the current page.
const unblock = history.block('Are you sure you want to leave this page?')
// Or use a function that returns the message when it's needed.
history.block((location, action) => {
// The location and action arguments indicate the location
// we're transitioning to and how we're getting there.
// A common use case is to prevent the user from leaving the
// page if there's a form they haven't submitted yet.
if (input.value !== '')
return 'Are you sure you want to leave this page?'
})
// To stop blocking transitions, call the function returned from block().
unblock()
https://github.com/mjackson/history#blocking-transitions

XCode 7 UI Testing: Dismissal of system-generated UIAlertController does not work

I have a UI test which involves the dismissal of a system-generated UIAlertController. This alert asks the user for the permission to access the device's calendar. The objective of the test is the behaviour after a tap on the OK button:
1 let app = XCUIApplication()
...
// this code was basically generated by the recording feature of XCode 7
2 app.alerts.elementBoundByIndex(0).collectionViews.buttons["OK"].tap()
Now, instead of clicking the OK button, line 2 makes the simulator tap onto the first button which happens to be the Cancel button...
Additionally, I found out that the testing framework does not accurately recognize the appearing alert. So if I check the current count of alerts I always get 0:
// ...tap...
let count = app.alerts.count // == 0
This also happens if I use an NSPredicate for the condition and wait for several seconds.
Is it possible that UI tests do not work reliably with system-generated alerts? I am using XCode 7.0.1.
Xcode 7.1 has finally fixed the issue with system alerts. There are, however, two small gotchas.
First, you need to set up a "UI Interuption Handler" before presenting the alert. This is our way of telling the framework how to handle an alert when it appears.
Second, after presenting the alert you must interact with the interface. Simply tapping the app works just fine, but is required.
addUIInterruptionMonitorWithDescription("Location Dialog") { (alert) -> Bool in
alert.buttons["Allow"].tap()
return true
}
app.buttons["Request Location"].tap()
app.tap() // need to interact with the app for the handler to fire
The "Location Dialog" is just a string to help the developer identify which handler was accessed, it is not specific to the type of alert. I believe that returning true from the handler marks it as "complete", which means it won't be called again.
I managed to dismiss access prompt for contacts like this:
let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"]
if alert.exists
{
alert.tap()
}
Replace asterisks with your app's name. It might work the same for calendar.
This is what I ended up using to get the prompt to appear and then allow access to Contacts:
func allowAccessToContacts(textFieldsName: String)
{
let app = XCUIApplication()
let textField = app.textFields[textFieldsName]
textField.tap()
textField.typeText("aaa")
let alert = app.alerts["\u{201c}******\u{201d} Would Like to Access Your Contacts"].collectionViews.buttons["OK"]
if alert.exists
{
alert.tap()
}
textField.typeText("\u{8}\u{8}\u{8}")
}

Detect if user Idle on windows universal app

I'm developing a class library for windows 10 universal apps (mobile and desktop device families only). I need to invoke an event if the user has been idle(no touch, mouse move, key press etc) for x number of seconds. This method can be used to solves this problem on android. But I couldn't find a solution on windows UWP.
Is there an API available in UWP to achieve this?
You can detect global input with various events on the app's CoreWindow:
Touch and mouse input with CoreWindow.PointerPressed, PointerMoved, and PointerReleased.
Keyboard input: KeyUp and KeyDown (the soft keys) and CharacterReceived (for characters generated via chords & text suggestions)
Use these to detect the user is active and idle out if it goes too long without any of these events.
I know this is really old question, but I think you can now get to same result with RegisterBackgroundTask
Just set:
new TimeTrigger(15, false) //For time trigger
Link
new SystemCondition(SystemConditionType.UserNotPresent)) //And so you want to know so user is not present
Link
Example usage in App.xaml.cs:
var builder = new BackgroundTaskBuilder();
builder.Name = "Is user Idle";
builder.SetTrigger(new TimeTrigger(2, false)); //two mins
builder.AddCondition(new SystemCondition(SystemConditionType.UserNotPresent));
// Do not set builder.TaskEntryPoint for in-process background tasks
// Here we register the task and work will start based on the time trigger.
BackgroundTaskRegistration task = builder.Register();
task.Completed += (sender, args) =>
{
//Handle user not present (Idle) here.
};