wix react native navigation v2 | unable to disable open gestures - react-native

In the RNN v1 we can use disableOpenGesture: true, but in v2 it doesn't work anymore. I tried the next but without success:
sideMenu: {
right: {
component: {
id: 'sideDrawer',
name: DRAWER,
options: {
disableOpenGesture: true,
}
}
},
center: {...}
}

I found a temporal solution that fits my use case (I have a hamburger button which toggle the drawer):
export const openDrawer = () => {
Navigation.mergeOptions('sideDrawer', {
sideMenu: {
right: {
enabled: true,
visible: true
}
}
})
}
export const closeDrawer = () => {
Navigation.mergeOptions('sideDrawer', {
sideMenu: {
right: {
visible: false,
enabled: false,
}
}
})
}
Basically I disable the drawer completely when it's not shown. When disabled obviously gestures are disabled as well. Again this fits my use case and might not suite anyone.
Edit: it turned out my solution works on iOS only but also has this issue:
https://github.com/wix/react-native-navigation/issues/3837.
On Android it doesn't work at all.
I'm using "react-native": "0.56.0" and "react-native-navigation": "2.0.2485".

Related

Vue3 vue-intersect not working with v-if?

When I use
<intersect v-if="activated == true" #enter=" addImages();" > <div class="h-1 w-full border"></div> </intersect>
The intersect appears in the dom when the condition is met, but the intersect is not doing any method anymore when I scroll to it.
If I remove the if then I have the problem that with a big screen when the page loads, the intersect gets activated a couple of times while loading.
How to make the intersect work with v-if? what is the reason that its not working?
Here the code of the intersect component ( from this project vue-intersect):
import Vue from 'vue'
const warn = (msg) => {
if (!Vue.config.silent) {
console.warn(msg)
}
}
export default {
name: 'intersect',
abstract: true,
props: {
threshold: {
type: Array,
required: false,
default: () => [0, 0.2]
},
root: {
type: typeof HTMLElement !== 'undefined' ? HTMLElement : Object,
required: false,
default: () => null
},
rootMargin: {
type: String,
required: false,
default: () => '0px 0px 0px 0px'
}
},
mounted () {
this.observer = new IntersectionObserver((entries) => {
if (!entries[0].isIntersecting) {
this.$emit('leave', [entries[0]])
} else {
this.$emit('enter', [entries[0]])
}
this.$emit('change', [entries[0]])
}, {
threshold: this.threshold,
root: this.root,
rootMargin: this.rootMargin
})
this.$nextTick(() => {
if (this.$slots.default && this.$slots.default.length > 1) {
warn('[VueIntersect] You may only wrap one element in a <intersect> component.')
} else if (!this.$slots.default || this.$slots.default.length < 1) {
warn('[VueIntersect] You must have one child inside a <intersect> component.')
return
}
this.observer.observe(this.$slots.default[0].elm)
})
},
destroyed () {
this.$emit('destroyed')
this.observer.disconnect()
},
render () {
return this.$slots.default ? this.$slots.default[0] : null
}
}
It seems you're installing the old version of this component which is not compatible with Vue 3, try to uninstall the installed version and install the next one
npm uninstall vue-intersect --save
then
npm install vue-intersect#next --save

Setting up react native push notification with wix react native navigation v3 - problem when app is closed

I am sending a notification that navigates the user to a specific screen when the notification is clicked.
This works perfectly when the app is opened or running in the background, however, when the app is closed onNotification is not being called.
I am using react native push notification and wix react native navigation V3.
I notice the problem by putting a console log inside on notification and it was never called.
In index.js I have the follwing code
import { start } from './App';
start();
In App.js
import React from 'react';
import { Navigation } from 'react-native-navigation';
import { Provider } from 'react-redux';
import configureStore from './src/configureStore';
import { configurePush } from './src/utils/push-notifications';
import Login from './src/components/views/Login';
import Home from './src/components/views/Home';
import Cart from './src/components/views/Cart';
import CartDetail from './src/components/views/Cart/Detail';
import Orders from './src/components/views/Orders';
... the rest of the screens
const store = configureStore();
configurePush(store);
export function registerScreens() {
Navigation.registerComponent('provi.Login', () => (props) => (
<Provider store={store}>
<Login {...props} />
</Provider>
), () => Login);
Navigation.registerComponent('provi.Home', () => (props) => (
<Provider store={store}>
<Home {...props} />
</Provider>
), () => Home);
Navigation.registerComponent('provi.Cart', () => (props) => (
<Provider store={store}>
<Cart {...props} />
</Provider>
), () => Cart);
... the rest of the screens
}
export function start() {
registerScreens();
Navigation.events().registerAppLaunchedListener(async () => {
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'provi.Login',
options: {
animations: {
setStackRoot: {
enabled: true
}
},
topBar: {
visible: false,
drawBehind: true,
background: {
color: '#30DD70'
},
},
bottomTabs: {
visible: false
}
}
}
}],
}
}
});
});
}
Then the configuration of the notification is the following:
import PushNotificationIOS from "#react-native-community/push-notification-ios";
import { Navigation } from 'react-native-navigation';
import PushNotification from 'react-native-push-notification';
import DeviceInfo from 'react-native-device-info';
import fetchApi from "../store/api";
import { addNotification } from '../store/notifications/actions';
import { SENDER_ID } from '../constants';
export const configurePush = (store) => {
PushNotification.configure({
onRegister: function(token) {
if (token) {
const registerData = {
token: token.token,
uid: DeviceInfo.getUniqueID(),
platform: token.os
}
// console.log(registerData);
fetchApi('/notificaciones/register', 'POST', registerData).catch(err => console.log(err))
}
},
onNotification: function(notification) {
if (notification) {
store.dispatch(addNotification(notification)); // Almacena la notification
const action = notification.data.click_action;
if (action === 'oferta') {
const remotePost = notification.data.data;
Navigation.setRoot({
root: {
stack: {
children: [{
component: {
name: 'provi.Home',
options: {
animations: {
setStackRoot: {
enabled: true
}
},
topBar: {
visible: true,
drawBehind: false,
},
passProps: {
test: 'test',
notification: remotePost
}
}
}
}],
}
}
});
} else if (action === 'seller') {
const remoteSeller = notification.data.data;
Navigation.push('Home', {
component: {
name: 'provi.Seller',
passProps: {
id: remoteSeller._id,
featureImage: remoteSeller.featureImage
},
options: {
topBar: {
title: {
text: 'Nueva Marca!'
}
},
bottomTabs: {
visible: false,
drawBehind: true
}
}
}
});
} else if (action === 'sellerClosingSoon') {
const remoteSeller = notification.data.data;
Navigation.push('Home', {
component: {
name: 'provi.ClosingSoon',
passProps: {
id: remoteSeller._id,
featureImage: remoteSeller.featureImage
},
options: {
topBar: {
title: {
text: 'Marcas que cierran pronto'
}
},
bottomTabs: {
visible: false,
drawBehind: true
}
}
}
});
}
}
notification.finish(PushNotificationIOS.FetchResult.NoData);
},
senderID: SENDER_ID,
popInitialNotification: true,
requestPermissions: true
});
}
I am expecting to see the console.log at least but it's not happening.
What is the correct setup for RNN V3 with RN push notification?
the notifications are two types: background and foreground.
You use foreground notifications. But when an app is closed and you receive a new notification your callback cannot be fired.
You should use something like getInitialNotification to get the notification data.
https://github.com/zo0r/react-native-push-notification/blob/master/component/index.android.js#L19
I hope that helps.
Thanks

Ask for permission in specific screen in android

For react native application navigation I use react-native-navigation v2 here I've created navigation with bottomTabs. Here is the navigation handler
import { Navigation } from "react-native-navigation";
import { width, height } from "../utils/screenResolution";
import { bottomTabIcon, topBarOpts } from "../components";
const sideBarWidth = width * 0.65;
export const goToAuth = () =>
Navigation.setRoot({
root: {
stack: {
id: "AuthNav",
children: [
{
component: {
name: "SignInScreen",
options: {
topBar: { visible: false, height: 0 }
}
}
}
]
}
}
});
export const goHome = async () => {
let icon1 = await bottomTabIcon("CollectionScreen", "Collection", "archive");
let icon2 = await bottomTabIcon("MainScreen", "Home", "home");
let icon3 = await bottomTabIcon("CaptureScreen", "Capture", "camera");
Navigation.setRoot({
root: {
sideMenu: {
right: {
component: {
name: "SideBar"
}
},
center: {
bottomTabs: {
id: "AppNav",
children: [icon1, icon2, icon3]
}
},
options: {
sideMenu: {
right: {
width: sideBarWidth
}
}
}
}
}
});
Navigation.mergeOptions("MainScreen", {
bottomTabs: {
currentTabIndex: 1
}
});
};
Icons tab creating with this bottomTabIcon function.
import Icon from "react-native-vector-icons/FontAwesome";
import { topBarOpts } from "./";
import { PRIMARY, BOTTOM_TAB_BACKGROUND, TAB_ICON } from "../../assets/color";
let bottomTabIcon = async (name, text, iconName) => {
let icon = {
stack: {
children: [
{
component: {
name: name,
id: name,
options: {
bottomTab: {
text: text,
fontSize: 12,
selectedIconColor: PRIMARY,
iconColor: TAB_ICON,
icon: await Icon.getImageSource(iconName, 20)
}
}
}
}
]
}
};
if (name === "CaptureScreen") {
icon.stack.children[0].component.options.bottomTabs = {
visible: false,
drawBehind: true,
animate: true
};
icon.stack.children[0].component.options.topBar = {
visible: false,
height: 0
};
} else {
icon.stack.children[0].component.options.bottomTabs = {
backgroundColor: BOTTOM_TAB_BACKGROUND
};
icon.stack.children[0].component.options.topBar = await topBarOpts("Example");
}
return icon;
};
export { bottomTabIcon };
Here is the problem, when user logging in application,its asking for permissions (camera,audio etc.) in MainScreen I want to do that in specific screen,after that I find out that all screens in bottomTabs mounted.So if I call something to do in componentDidMount in CaptureScreen it will work in MainScreen.How I can solve this part? I am pretty new in react-native so something you can find weird in this code.Thanks for help and for attention.
Have the permission calls only in did mount of the specific screens or in the child screen where it is needed not in the parent screen or in navigators.
In your case you are calling them by taking the route index in the react navigation. Add the permission code on the child screen or where the permissions are required and they will start working.

How can I update a custom top bar title component in React Native Navigation v2?

I'm trying to update a custom topBar title component after it has already become visible. I've tried calling Navigation.mergeOptions and using passProps with no luck.
Initial options:
...
static options(passProps) {
return {
topBar: {
title: {
component: {
id: "rn.MyCustomTopBar",
name: "rn.MyCustomTopBar",
alignment: "fill",
passProps: {
dynamicField: "Initial Value"
}
}
}
}
};
}
...
Using mergeOptions:
...
Navigation.mergeOptions(this.props.componentId, {
topBar: {
title: {
component: {
passProps: {
dynamicField: "New Value"
}
}
}
}
});
...
There appears to be a closed issue on GitHub regarding mergeOptions on custom components, https://github.com/wix/react-native-navigation/issues/3782, saying it will be resolved in #3030, however that issue does not have a milestone and hasn't had any activity since June. https://github.com/wix/react-native-navigation/issues/3030
If anyone can provide a work around and example on how this can be achieved it'd be greatly appreciated.
The custom top bar can be updated by passing a reference back to the parent through passProps. The parent can then use the reference to call a function within the top bar that will change its state appropriately.
Parent component:
...
constructor() {
super(props);
Navigation.events().bindComponent(this);
this._customTopBar = null;
}
...
componentDidMount() {
Navigation.mergeOptions(this.props.componentId, {
topBar: {
title: {
component: {
passProps: {
passRef: ref => {
this._customTopBar = ref;
}
}
}
}
}
});
}
...
// called whenever custom title needs to be updated
this._customTopBar.updateState(...);
...
Custom component:
...
componentDidMount() {
this.props.passRef(this);
}
...
updateState(...) {
this.setState(...);
}
...
Note: This has not been tested on Android.

React Native Share Method Multiple Windows

I’m using react native share, to share text content. The issue is multiple windows are opened over each other on clicking share button multiple times. Even I have disabled button on share click but it is of no use as well.
The standard way is if share window is already open, on clicking the share button again the window get closed. How can it be done?
<Button
transparent
disabled={this.state.isShareDisabled}
onPress={() => this.onShare()}>
onShare() {
if(!this.state.isShareDisabled)
{
this.setState(
{
isShareDisabled:true
}
)
Share.share({
message: “Message test”,
url: ”www.google.com”,
title: “Title test”
}, {
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
}) .then((result) => {
this.setState(
{
isShareDisabled: false,
}
)
})
}
}
Use dismissed action. Share event support it on both android and iOS.
I resolved it by doing the following, just required to check dismissedAction.
onShare() {
if(!this.state.isShareDisabled)
{
this.setState(
{
isShareDisabled:true
}
)
Share.share({ message: 'test',
url: 'test url',
title: 'test title'
},
{
// Android only:
dialogTitle: 'Share',
// iOS only:
excludedActivityTypes: [
'com.apple.UIKit.activity.PostToTwitter'
]
}).then(({action, activityType}) => {
if(action === Share.dismissedAction) {
this.setState(
{
isShareDisabled: false,
}
)
}
else {
this.setState(
{
isShareDisabled: false,
}
)
}
});
}
}