How do I disable the device back button on Android (react-native)? - react-native-navigation

How can I disable the physical device back button on Android with React-Native? I don't want to enable it for the user.

There is no out of the box support from React Native Navigation as of today on v2. However, you could use BackHandler from React native itself. To handle it and return false to disable it.
Doc on BackHandler
Example
BackHandler.addEventListener('hardwareBackPress', function() {
return false;
});

In activity you can override the onBackPressed() and comment the calling to super class.
#Override
public void onBackPressed() {
// super.onBackPressed(); comment this line to disable back button press
}

Current open screen is tracked with a listener created when the application is launched, in app.js. Main component of the app creates a BackHandler listener, which responds to the device back button according to the currently open screen.
Main component:
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
if (this.props.currentScreen.name === 'app.main') {
Alert.alert(
'Confirm exit',
'Do you want to exit App?',
[
{text: 'CANCEL', style: 'cancel'},
{text: 'OK', onPress: () => {
BackHandler.exitApp()
}
}
]
);
} else {
Navigation.pop(this.props.currentScreen.id);
}
return true;
}
App.js
//register to compomentDidApperaListener to keep track on which screen is currently open. The componentName and Id are stored in my redux store
Navigation.events().registerComponentDidAppearListener(({ componentId, componentName }) => {
store.dispatch(updateCurrentScreen({'name': componentName, 'id': componentId}))
})

Related

Flutter_web detect mouse hover and click in HtmlElementView

I am using flutter web to parse some website.
I need to detect the mouse hover and click inside a htmlElementView and then get the corresponded element. I tried to listen the onMouseUp() but it didn't work. can you give me advise?
Widget myfunc(){
ui.platformViewRegistry.registerViewFactory(
'my-html',
(int viewId) => IFrameElement()
..style.border = 'none'
..srcdoc = webData
..onMouseUp.listen((event) {
print('onMouseUp => $event');
})
..onSelect.listen((event) {
print('onSelect => $event');
})
..onMouseDown.listen((event) {
print('onMouseDown=> $event');
})
..onMouseEnter.listen((event) {
print('onMouseEnter => $event');
})
);
return HtmlElementView(
viewType:'my-html',
);
}
I plan to follow this post to extract the element, but it only work outside of htmlElementView().
How to get the selected text or the inner html in Dart
I don't find what is wrong but I use followed solution as an alternate.
I insert the JavaScript and listen to postMessage() on Dart side.
Step 1. add postMessage() in the HTML. I parse entire web HTML and insert the event.
var newElement = html.Element.html(element.outerHtml);
print('newElement=> ${newElement.outerHtml}');
newElement.attributes['onmouseover'] = 'window.parent.postMessage(this.id, \'*\')';
Step 2. Add the listener on the Dart side.
#override
void initState(){
super.initState();
html.window.onMessage.listen( listen);
}
void listen(dynamic event) {
print('listen...');
var data = (event as html.MessageEvent).data;
print(data);
}

Xamarin IOS - Show local notification when application is closed

I have a Xamarin IOS application that get's the users location each 10 sec, even when the app is killed. I make us of this library: "https://jamesmontemagno.github.io/GeolocatorPlugin/".
What I want is: When the app is closed or open and the user is at a specific location, I want to show a local notification. Is that even possible when the app is closed? I can't find information on this because it's always about remote notifications.
Notification permission should be requested as soon as the app launches by adding the following code to the FinishedLaunching method of the AppDelegate and setting the desired notification type (UNAuthorizationOptions):
...
using UserNotifications;
...
public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
....
//after iOS 10
if(UIDevice.CurrentDevice.CheckSystemVersion(10,0))
{
UNUserNotificationCenter center = UNUserNotificationCenter.Current;
center.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.UNAuthorizationOptions.Badge, (bool arg1, NSError arg2) =>
{
});
center.Delegate = new NotificationDelegate();
}
else if(UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Alert| UIUserNotificationType.Badge| UIUserNotificationType.Sound,new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
return true;
}
New to iOS 10, an app can handle Notifications differently when it is in the foreground and a Notification is triggered. By providing a UNUserNotificationCenterDelegate and implementing the UserNotificationCentermethod, the app can take over responsibility for displaying the Notification. For example:
using System;
using ObjCRuntime;
using UserNotifications;
namespace workplat
{
public class NotificationDelegate:UNUserNotificationCenterDelegate
{
public NotificationDelegate()
{
}
public override void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action<UNNotificationPresentationOptions> completionHandler)
{
// Do something with the notification
Console.WriteLine("Active Notification: {0}", notification);
// Tell system to display the notification anyway or use
// `None` to say we have handled the display locally.
completionHandler(UNNotificationPresentationOptions.Alert|UNNotificationPresentationOptions.Sound);
}
public override void DidReceiveNotificationResponse(UNUserNotificationCenter center, UNNotificationResponse response, Action completionHandler)
{
// Take action based on Action ID
switch (response.ActionIdentifier)
{
case "reply":
// Do something
break;
default:
// Take action based on identifier
if (response.IsDefaultAction)
{
// Handle default action...
}
else if (response.IsDismissAction)
{
// Handle dismiss action
}
break;
}
// Inform caller it has been handled
completionHandler();
}
}
}
To create and register a Custom Action with the system, use the following code:
public void RegisterNotification(long time)
{
UNUserNotificationCenter center = UNUserNotificationCenter.Current;
//creat a UNMutableNotificationContent which contains your notification content
UNMutableNotificationContent notificationContent = new UNMutableNotificationContent();
notificationContent.Title = "xxx";
notificationContent.Body= "xxxx";
notificationContent.Sound = UNNotificationSound.Default;
UNTimeIntervalNotificationTrigger trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(time, false);
UNNotificationRequest request = UNNotificationRequest.FromIdentifier("FiveSecond", notificationContent, trigger);
center.AddNotificationRequest(request,(NSError obj) =>
{
});
}
When you call this method ,for emample:
RegisterNotification(20);//set the time you want to push notification
The notification will been pushed after 20 seconds,enen if you close your app. You could put this line after uploading the location .
I have upload my demo to my github, you can download it for your reference: Demo Link .
And you can access the link for more information and details: MicroSoft Document

angular route static paths access urls directly without permission

I am trying to fix a bug in a web application using java 8, spring boot, Spring MVC and front end with angular cli. When the user logins the application and is created a menu considering the user profile permission with java, but the application uses angular router with static paths, so if the user rewrite the URL he can access anything even without permissions.
const routes: Routes = [
{
path: '',
component: WebservicesComponent,
children: [
{ path: 'perfis', loadChildren: './wsperfis/wsperfis.module#WsperfisModule', },
{ path: 'acessos', loadChildren: './wsacessos/wsacessos.module#WsacessosModule', },
{ path: 'novoAcesso', loadChildren: './novo-acesso/novo-acesso.module#NovoAcessoModule', },
{ path: 'servicos', loadChildren: './wsservicos/wsservicos.module#WsservicosModule' },
{ path: 'novoperfil', loadChildren: './wsnovoperfil/wsnovoperfil.module#WsnovoperfilModule' }
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class WebservicesRoutingModule {
}
#CrossOrigin
#RequestMapping("/menu")
public List<Object> menu(#RequestParam(value = "idPerfil") int idPerfil) {
List<Menu> menus = menuService.getMenus(idPerfil);
List<Object> menu = new ArrayList<Object>();
Map<String, Object> mapMenu = new HashMap<String, Object>();
Map<String, String> mapSubMenu = new HashMap<String, String>();
List<Object> listMapSubMenu = new ArrayList<Object>();
for (Menu menuItem : menus) {
if (!mapMenu.containsValue(menuItem.getPaiPrompt())) {
mapMenu = new HashMap<String, Object>();
listMapSubMenu = new ArrayList<Object>();
mapMenu.put(LABEL, menuItem.getPaiPrompt());
mapMenu.put(URL, menuItem.getPaiUrl());
mapMenu.put(ICON, menuItem.getPaiIcon());
for (Menu submenu : menus) {
if (menuItem.getPaiPrompt().equals(submenu.getPaiPrompt())) {
mapSubMenu = new HashMap<String, String>();
mapSubMenu.put(LABEL, submenu.getFilhoPrompt());
mapSubMenu.put(URL, submenu.getFilhoUrl());
mapSubMenu.put(ICON, submenu.getFilhoIcon());
listMapSubMenu.add(mapSubMenu);
}
}
mapMenu.put(ITEMS, listMapSubMenu);
menu.add(mapMenu);
}
}
return menu;
}
You should add a validation on your front and backend, for example, when path changes in frontend and component is mounted it checks for session sending its path id, backend compare that versus asigned menu, all this before making any other api call.
Another solution more complex (and secure) is adding the validation on api itself, by checking menus or user profiles, this way even if user access a page he should not (its mapped in js), he won't access unauthorized apis.
I could do it using a canActiveChild validation in a Guard file, but now I am if a issue in the first time that I call it.
The service that a call there stay with the status pending in the the first time that I call it, but in the next calls it works fine.
Fallow the code:
constructor(private router: Router, private _cookieService: CookieService, private comumService: ComumService) {}
canActivate() {
if (this._cookieService.get('AuthorizationToken')) {
return true;
}
this.router.navigate(['login']);
return false;
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
console.log('state.url: ' + state.url);
// tslint:disable-next-line:triple-equals
if (state.url == '/dashboard' || this.validaAcesso(state.url)) {
return true;
} else {
console.log('Entrou aqui!!!');
window.alert('You don\'t have permission to view this page');
this.router.navigate(['dashboard']);
return false;
}
}
validaAcesso(url: string) {
this._cookieService.getAll();
this.comumService.validaAcesso(url).subscribe((data: Boolean) => {
console.log(data.valueOf());
if (data.valueOf()) {
console.log('validaAcesso return true');
this.result = true;
} else {
console.log('validaAcesso return false');
this.result = false;
}
});
return this.result;
}
}

Access component state when user is going to previous scene

react-native-router-flux version: 3.39.1
Hi, i need to access to component state when the user clicks on Back button of navbar to go to previous scene .
Is there a way of doing this ?
i need this to verify the state if the user did some working on any textInput.
https://github.com/aksonov/react-native-router-flux/issues/647
If you use the "cheat" that jo-asakura says, you be able to access component state onBack button :)
// your scene
<Scene key="someKey"
component={ SomeComponent }
onRight={
(state) => {
// state.scene.navigationState.myData is { hello: 'world' }
}
} />
// your component
class SomeComponent extends Component {
// ...
handleButtonClick() {
this.props.navigationState.myData = { hello: 'world' };
}
// ...
}
PS: in my case i have put this line at render function to always save new data.
render(){
this.props.navigationState.myData = this.state;
return()
}

Microsoft Bot Framework - Proactive message, suspend current dialog

I've created a simple news bot which sends updates to a user every 24 hours. I've created a callback controller which handles requests from an external service, processes the resumptionCookie, then sends a carousel of articles with two buttons to the user. One of the buttons opens a browser window, the other should trigger a new dialog (OptionsDialog).
Is this implementation correct? and is it possible to suspend any active dialog, whilst the user interacts with the news article message? For example, if i'm going through a particular dialog, then suddenly I get a news alert, is it possible to suspend the current dialog, to allow the user to update the options of the alerts (almost like the news alert is outside the normal dialog flow), then once they've finished they'll return to the previous dialog. Hopefully, the question is clear enough. Any help will be greatly appreciated.
public class CallbackController : ApiController
{
public async Task<IHttpActionResult> Post(ResumptionCookie resumptionCookie)
{
var activity = (Activity)resumptionCookie.GetMessage();
var reply = activity.CreateReply();
reply.Text = "We found 7 news articles that match your criteria";
reply.Attachments = new List<Attachment>
{
new ThumbnailCard
{
Buttons = new List<CardAction>
{
new CardAction(ActionTypes.OpenUrl, "BBC", null, "http://www.bbc.co.uk"),
new CardAction(ActionTypes.PostBack, "Update Options", null, "Update Options")
}
}.ToAttachment()
};
var client = new ConnectorClient(new Uri(activity.ServiceUrl));
await client.Conversations.ReplyToActivityAsync(reply);
return Ok(new { success = true });
}
}
This is my Main dialog
[Serializable]
public class MainDialog : IDialog
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(ProcessMessage);
}
private async Task ProcessMessage(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var response = await result;
if (response.Text.Equals("Update Options", StringComparison.OrdinalIgnoreCase))
{
context.Call(new OptionsDialog(), FinishMainDialog);
}
else
{
PromptDialog.Confirm(context, ProcessChoice, "Do you wish to continue?");
}
}
private async Task ProcessChoice(IDialogContext context, IAwaitable<bool> result)
{
var choice = await result;
if(choice)
{
context.Call(new DialogOne(), FinishMainDialog);
}
else
{
context.Done(true);
}
}
private async Task FinishMainDialog(IDialogContext context, IAwaitable<object> result)
{
context.Done(true);
}
}
Here is my frequency dialog
[Serializable]
public class OptionsDialog : IDialog
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("You can update your to options here");
context.Wait(ProcessMessage);
}
public async Task ProcessMessage(IDialogContext context, IAwaitable<IMessageActivity> activity)
{
await context.PostAsync("Hello, World!");
context.Done(true);
}
}

Resources