Closed gvsakhil closed 4 years ago
Strange! In order to help debug, do you mind creating a working example app I can download and run? That would help tremendously. Cheers.
I'm having this issue on Android only. iOS works as expected.. I've got a component called ScreenContainer which checks network availability:
class ScreenContainer extends Component<Props, State> {
componentDidUpdate(prevProps: Props) {
this.checkNetworkAvailability(prevProps);
}
checkNetworkAvailability(prevProps?: Props) {
if (
prevProps &&
!prevProps.networkAvailable &&
this.props.networkAvailable
) {
console.warn("Snackbar dismiss");
// Dismiss ANY existing Snackbars: https://github.com/cooperka/react-native-snackbar#snackbardismiss
Snackbar.dismiss();
} else if (!this.props.networkAvailable) {
console.warn("Snackbar show, networkAvailable:", this.props.networkAvailable);
try {
Snackbar.show({
text: "No network",
duration: Snackbar.LENGTH_INDEFINITE,
action: __DEV__ && {
text: "(dev) UNDO",
textColor: "green",
onPress: () => {
/* Do something. */
}
}
});
} catch (error) {
console.error("showing snackbar failed");
}
}
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
...
</SafeAreaView>
);
}
}
const mapStateToProps = (state: GlobalState): MapStateToProps => {
return {
networkAvailable: state.api.networkAvailable
};
};
export default connect(mapStateToProps)(ScreenContainer);
I use this in other class components:
render() {
return (
<ScreenContainer>
...
</ScreenContainer>
);
}
I'm seeing all the console warnings as expected, but the Snackbar is not showing up.
The Snackbar does show up when a class component using ScreenContainer is mounted (componentDidMount). Then toggling airplane mode dismisses the Snackbar but it will not reappear again.. While console warnings show Snackbar show, networkAvailable: false
The console.error is never thrown.
npx react-native info
:
System:
OS: macOS 10.15.5
CPU: xxxxx
Memory: xxxxx
Shell: xxxxx
Binaries:
Node: 13.7.0 - /usr/local/bin/node
npm: 6.14.5 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
Android SDK:
API Levels: 28, 29
Build Tools: 28.0.3, 29.0.3, 30.0.0, 30.0.0
System Images: android-29 | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.6 AI-192.7142.36.36.6392135
Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild
npmPackages:
@react-native-community/cli: ^4.0.1 => 4.10.0
react: 16.9.0 => 16.9.0
react-native: ~0.61.5 => 0.61.5
npmGlobalPackages:
react-native-ble-plx: 1.0.3
react-native-create-library: 3.1.2
react-native-git-upgrade: 0.2.7
react-native-permissions: 1.1.1
EDIT: added react-native info
I found what I was doing wrong. For turning off/on network capabilities I swiped down my QuickSettings pane. By doing this the application window loses focus. There are numerous cases where this is unexpected behaviour and you fail to deliver your message to the user.
I put breakpoints at line 66 and 68 in SnackbarModule.java, they were triggered when QuickSettings was visible. But 71: displaySnackbar(modal, options, callback);
was not..
Note to self:
Toggle network by adb
:
adb shell svc wifi disable
-- and --
adb shell svc wifi enable
I did managed to get around this issue by altering SnackbarModule.java. I'll see if I can submit a PR.
hasWindowFocus()
: https://developer.android.com/reference/android/app/Activity#hasWindowFocus()
getVisibility()
: https://developer.android.com/reference/android/view/View#getVisibility()
Old
if (!view.hasWindowFocus()) {
// The view is not focused, we should get all the modal views in the screen.
ArrayList<View> modals = recursiveLoopChildren(view, new ArrayList<View>());
for (View modal : modals) {
if (modal == null) continue;
displaySnackbar(modal, options, callback);
}
return;
}
New
if (!view.hasWindowFocus()) {
// The view is not focused, we should get all the modal views in the screen.
ArrayList<View> modals = recursiveLoopChildren(view, new ArrayList<View>());
if (modals.size() > 0) {
for (View modal : modals) {
if (modal == null) continue;
displaySnackbar(modal, options, callback);
}
} else if (view.getVisibility() == View.VISIBLE) {
displaySnackbar(view, options, callback);
}
return;
}
I am trying to show some toasters based on api response and if I add a snackbar before try block its working fine and the snackbar that are inisde try, catch blocks are not being executed. I try settimeout but it didn't work for me.
package.json
"react": "16.9.0", "react-native": "0.61.5", "react-native-snackbar": "^2.0.3",
My Code
async function sendEmail() { Snackbar.show({ title: 'Reset link sent successfully', duration: Snackbar.LENGTH_INDEFINITE, }); setLoading(true); try { const res = await axios.post(
${Constants.apiUrl}auth/requestresetpassword/${email}/WITTYPARROT
, {}); if (res.status == 202) { Snackbar.show({ title: 'Reset link sent successfully', duration: Snackbar.LENGTH_INDEFINITE, }); } setLoading(false); } catch (e) { console.log(e.response.status); if (e.response.status == 400) { Snackbar.show({ title: 'Please enter a valid email address', duration: Snackbar.LENGTH_INDEFINITE, }, 1000); } else { Snackbar.show({ title: 'Something went wrong', duration: Snackbar.LENGTH_SHORT, }, 1000); } setLoading(false); } }