React Native Navigation: how to disable backbutton on modals? - react-native-navigation

I've a login modal opened using showModal().
It has no navbar buttons, so ios users cannot close this modal.
Problem: Actually Android users can use hardware back button to close the login modal.
In my login modal I tried to add
BackHandler.addEventListener('hardwareBackPress', function() {
return true;
}
to disallow backbutton on Android, but it simply doesn't works.
I did this because I read what follows on official RN guide:
Android: Detect hardware back button presses, and programmatically invoke the default back button functionality to exit the app if there are no listeners or if none of the listeners return true.
Adding a console.log into this function I see the event fired on 'normal' screens but NOT when I've a modal showed !
What am i doing wrong?

Overriding hardware back button is possible using overrideBackPress property as described here
You can handle the back press in your component:
onNavigatorEvent(event) {
if (event.id === 'backPress') {
//Do your thing
}
}

Related

Web control browser back button

I'm using Navigation 2 and setUrlStrategy(PathUrlStrategy());
I added WillPopScope but the onWillPop is not called when clicking the browser's back button.
Widget build(context) {
return WillPopScope(
onWillPop: () async {
print('here');
if (currentStep == 0) {
return false;
}
return true;
},
child: Scaffold(...
In Navigator 2.0, web browsers are chronological and basically treat all navigation as pushes.
Scenario:
Navigate from screen 1 to screen 2
Click the browser's back button.
In this scenario, Flutter will push the previous route (screen 1) onto the stack.
In other words, the browser back button no longer triggers onPopRoute. Instead it triggers onPushRoute.
I believe it was designed this way so that every navigation action can be treated as a deeplink. With that in mind, if you're developing a Flutter app for the web you should avoid passing arguments from one route to another as much as possible.
https://github.com/flutter/flutter/issues/71122#issuecomment-733864359

Is there a way to prevent the user pressing the back button on their device from popping the current view from the stack?

I'm using React-Native-Navigation from Wix (version 2) to setup navigation in my React Native app. I'm using the sideMenu layout with the center section being a stack. When the user selects one of the side menu items the selected view is pushed onto that center stack. If the user presses their back button on Android, then the view is popped from the stack, but I don't always want this to happen, mainly if the view they selected is a WebView.
If the view is a WebView, I want to manually handle the user pressing the hardware back button. If the WebView can "goBack" then the view will go back, but if it can't then the view will be popped from the stack (as it normally would).
I've tried overriding the back button press using the BackHandler class from react-native and this allows me to capture that press and have the WebView go back if able, but the act of popping the view from the stack also fires. Is there a way in React-Native-Navigation v2 to tell it, "Hey I got this, don't pop unless I tell you to."?
My current code for this section is as follows:
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.backHandler);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.backHandler);
}
backHandler = () => {
if (this.state.canGoBack) {
this.webviewRef.current.goBack();
// I thought this might force the back press to be
// ignored by react-native-navigation, but no dice.
return false;
} else {
// WebView can't go back so pop view like normal
Navigation.pop(this.props.componentId);
}
}
I was expecting this to only pop the view from the stack if the WebView can't currently go back and otherwise just have the WebView go back.
What actually occurs is both events fire. I.e. the WebView goes back, but the view is also popped from the stack.
I was able to find the answer to this through some more digging in the React Native Navigation and React Native docs.
The event subscriptions are called in reverse order (i.e. last registered subscription first), and if one subscription returns true then subscriptions registered earlier will not be called.
So the issue was in my backHandler method. Instead of returning false I needed to return true.
backHandler = () => {
if (this.state.canGoBack) {
this.webviewRef.current.goBack();
// We've handled the event so we return true and the
// handler on the view's parent can effectively be ignored. Yay!
return true;
} else {
// WebView can't go back so pop view like normal
Navigation.pop(this.props.componentId);
}
}

How find to whether my Chrome extension was called by shortcut?

I have a Chrome extension with a popup that can also be opened by a shortcut. When the popup gets opened, can I find out whether the user has used the shortcut or whether they have clicked on the extension icon?
The reason is that I'd like to hint users to use the shortcut, but I don't want to show that hint to users who already know and use the shortcut.
Popup and shortcut are defined like this in manifest.json:
"browser_action": {
"default_icon": "images/icon48.png",
"default_popup": "popup.html",
"default_title": "__MSG_tooltip__"
},
"commands": {
"_execute_browser_action": {
"suggested_key": {
"default": "Ctrl+Shift+Space"
}
}
},
chrome.browserAction.onClicked.addListener
Not available, because:
Fired when a browser action icon is clicked. This event will not fire
if the browser action has a popup.
We has popup.
chrome.commands.onCommand.addListener
Not available, because:
The '_execute_browser_action' and '_execute_page_action' commands are
reserved for the action of opening your extension's popups. They won't
normally generate events that you can handle.
May try inject press listener to some page and track pressed of keys (on each page).
var isPressed;
document.body.addEventListener("keydown", function (e) {
if (!(e.keyCode != 17) || !(e.keyCode != 16) || !(e.keyCode != 32)) return;
isPressed = true;
});
From popup in moment expand send message to content_scripts:
chrome.tabs.query({active: true, currentWindow: true}, function (tabs) {
chrome.tabs.sendMessage(tabs[0].id, {action: "isPressed"}, function (responce) {
if (responce) {
}
});
});
After message receiving, listener in content scripts send variable isPressed as response:
chrome.runtime.onMessage.addListener(function (message, sender, response) {
if (message.action == "isPressed") {
response(isPressed);
}
});
If variable is true, means called via keystrokes, else on click on icon.
can I find out whether the user has used the shortcut or whether they
have clicked on the extension icon?
There seems to be no clean direct way of detecting that.
Since I put some effort into trying to find a workaround, I would like to share what I have considered/tried and reasons why it doesn't work:
Attach the keyboard shortcut to some custom command, modify popup page and then open it programmatically.
Doesn't work because there is no way to open the popup programmatically, at least not in current stable version of Chrome (v50).
Create a custom command with the same shortcut as "_execute_browser_action" and use it to send a message to the popup.
Doesn't work because two commands cannot share the same shortcut.
Try to capture keyup in the popup page immediately after loading.
I tested this and it seemed to work at first, but it is definitely not reliable. If the user only presses the keyboard shortcut very briefly, the keyup event is fired before the popup page gets a chance to register a listener for it.
Capture keydown on pages using a content script and then send a message to the popup page to let it know that the keyboard shortcut was pressed (as suggested by UserName above).
This should work on most pages, but the content script won't be able to capture the keypress in address bar and on certain pages (chrome://, chrome-extension://).
Difficult to implement because you need to take into account the fact that users can customize the shortcut on chrome://extensions page. Finding the currently assigned shortcut programmatically to test against it in the content script is surprisingly difficult, because chrome.commands.getAll() provides localized key names (eg. "Ctrl+Shift+Space" in English, but "Ctrl+Shift+Mezera" in Czech) There are languages where even Ctrl and Shift don't stay in English.

How to write an extension to close tabs on "back" attempt when there's no previous page?

I find myself more and more using the touchpad gesture of 3 fingers to the left or right in order to perform a "back" or "forward" in Google Chrome (on my Asus Zenbook, but I believe there's a similar gesture on Macs)
I found that when browsing, I open a tab to read something (Like a like from Twitter or Facebook) and when I'm done my instinct is to go "back" to get back to the previous tab I was browsing on. (I think I got that instinct from using Android a lot).
I figured that I need a Chrome extension that would close my current tab if I'm attempting to go "back" in a tab that doesn't have a previous page in its history.
I went over the Chrome events and various methods I can invoke and while there's a "forward_back" transition qualifier in the WebNavigation api, the onCommitted event doesn't fire when attempting to go "back" using the touchpad gesture or Alt+left keyboard shortcut.
Also, I couldn't find how I can access a current tab's history to see if the page I'm at doesn't have a previous one in the stack.
Ideas anyone?
function noHistory(tabId) {
// TODO
}
function getCurrentTabId() {
// TODO
}
function userHitBack() {
tabId = getCurrentTabId();
if (noHistory(tabId)) {
chrome.tabs.remove(tabId)
}
}
function attachEvent() {
// TODO attach userHitBack
}
attachEvent();
To catch the "back" event, you need to handle specific key pressed to call your "userHitBack" function. Something like this:
document.onkeydown = function() {
if (keyId == ...)
userHitBack()
}
You can use this to your advantage as you can bind any key to trigger the close of the tab.
To check the tab history length use this:
window.history.length
It is html5 historyAPI

jQuery or JS handling browsers back button

Any ideas how to intercept the browser back button via jQuery, so I can run my event function?
I don't need to use jQuery BBQ or jQuery Address, only prevent the default behaviour and run it later after some animate.
Thank you!
d
Have not tried but i guess this do what you want.
window.onbeforeunload = function () {
// stuff do do before the window is unloaded here.
}
with jQuery you could try the .unload() function
The unload event is sent to the window
element when the user navigates away
from the page. This could mean one of
many things. The user could have
clicked on a link to leave the page,
or typed in a new URL in the address
bar. The forward and back buttons will
trigger the event. Closing the browser
window will cause the event to be
triggered. Even a page reload will
first create an unload event.
In jQuery land:
$(window).unload( function () { /*code here*/ });
EDIT- There was a parentheses instead of a close bracket
EDIT - Removed Extra Semicolin

Resources