Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add possibility to listen to react model open/request close #2

Conversation

maciekstosio
Copy link
Owner

@maciekstosio maciekstosio commented Jul 9, 2024

Summary:

At Reanimated we currently facing an issue that we're not able to listing to keyboard height changes in modal. This is due to the fact that android dialogs are attached next to the view tree, so we need to start observing insets on them separately, thus we need to listen to dialog open. To my knowledge, currently, there is no way to detect/listen when modal (dialog) is opened in a way that we can have access to its window (which we need to observe insets). The only hack that I found is listening to all events and act on “showModal”, which seems like hacky approach. In this PR I added observer that would be notified by ReactModalHostManager and would allow to attach listeners in other places. With this change in other packages we could get an instance and listen for those events. That should allow us to fix software-mansion/react-native-reanimated#5916 and may help with kirillzyusko/react-native-keyboard-controller#369.

Changelog:

[ANDROID] [ADDED] - Allow to listen to RN Modal events in native code.

Test Plan:

Tested on clean project from npx @react-native-community/cli@next init MyApp --version next --skip-install, which installs RN: 0.75.0-rc.5.

Tested with following part added to MainApplication.kt onCreate:
Changes in RN Core as in the PR.

Part added to MainApplication.kt onCreate:
ModalEventManager.addModalListener(object: ModalCallback {
      override fun onModalOpen(dialog: DialogInterface?, viewTag: Int) {
        println("Open")
        (dialog as Dialog).setOnDismissListener({
          println("Close")
        })
      }

      override fun onModalRequestClose(dialog: DialogInterface?, viewTag: Int) {
        println("onRequestClose")
      }
    })
  }
App.ts
import * as React from 'react';
import {
  TextInput,
  View,
  Button,
  Modal,
  SafeAreaView,
  StyleSheet,
} from 'react-native';

function MyModal({ visible, hide }) {
  const [isVisible, setIsVisible] = React.useState(false);

  return (
    <Modal transparent visible={visible} onDismiss={hide} onRequestClose={hide} onLayout={(layout) => console.log('layout', layout)}>
      <View style={styles.modalContainer}>
        <View style={styles.modalContent}>
          <Button onPress={hide} title="Close Modal" />
          <TextInput style={styles.textInput} placeholder="Inside a modal" />
          <Button onPress={() => setIsVisible(visible => !visible)} title="Toggle Component With Animated Keyboard" />
        </View>
      </View>
    </Modal>
  );
}

export default function EmptyExample() {
  const [visible, setVisible] = React.useState(false);

  return (
    <>
      <SafeAreaView style={styles.container}>
        <Button onPress={() => setVisible(true)} title="Open Modal" />
        <TextInput style={styles.textInput} placeholder="Outside a modal" />
      </SafeAreaView>
      <MyModal visible={visible} hide={() => setVisible(false)} />
    </>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'space-between',
    backgroundColor: '#ecf0f1',
    paddingHorizontal: 8,
    paddingBottom: 50,
    paddingTop: 8,
  },
  modalContainer: {
    ...StyleSheet.absoluteFillObject,
    flex: 1,
    justifyContent: 'center',
    backgroundColor: 'rgba(0,0,0,0.2)',
  },
  modalContent: {
    justifyContent: 'space-between',
    backgroundColor: 'white',
    borderRadius: 24,
    padding: 24,
    minHeight: 256,
  },
  textInput: {
    paddingHorizontal: 8,
    paddingVertical: 4,
    borderRadius: 8,
    backgroundColor: 'silver',
    fontSize: 18,
    textAlign: 'center',
  },
});
Screen.Recording.2024-07-18.at.15.47.57.mov

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant