Как сделать модал поверх экрана - PullRequest
0 голосов
/ 02 мая 2019

Я использую облачные сообщения Firebase в своем собственном приложении. У меня есть обычный класс (не реагирующий компонент) со статическими методами и переменными, который создается при запуске приложения. В этом классе есть три статических метода / слушателя (передний план, фон и приложение запуска) для управления push-уведомлениями из firebase.

Я пытаюсь справиться с действиями, когда на переднем плане. Как сделать модал поверх экрана (не переключая экраны, а запустить оверлейную карту в центре с двумя кнопками), когда пользователь получает push-сообщение от firebase, независимо от того, на каком экране он работает?

Пробное решение, предоставленное в этой статье на hackernoon, обертывание модального компонента внутри AppContainer ничего не сделало. https://hackernoon.com/managing-react-modals-with-singleton-component-design-5efdd317295b

Я также попробовал идею этого урока с модальным компонентом, но ни в одном случае не преуспел. https://reactnavigation.org/docs/en/navigating-without-navigation-prop.html

Класс облачных сообщений Firebase:

 export default class FCM {
static appClosedListener = async () => {
    const firebaseContent = await firebase.notifications().getInitialNotification();

    if (firebaseContent) {
      console.log(firebaseContent);
      const serverParcel = JSON.parse(firebaseContent._data.payload).an;
      const notificationState = "closedapp";
      FCM.pushNotificationHandler(serverParcel, notificationState);
    }
  };

  static backgroundListener = () => {
    FCM.background = firebase.notifications().onNotificationOpened(firebaseContent => {
      const serverParcel = JSON.parse(firebaseContent._data.payload).an;
      const notificationState = "background";
      FCM.pushNotificationHandler(serverParcel, notificationState);
    });
  };

  static foregroundListener = () => {
    FCM.foreground = firebase.notifications().onNotification(firebaseContent => {
      const serverParcel = JSON.parse(firebaseContent._data.payload).an;
      const notificationState = "foreground";
      FCM.pushNotificationHandler(serverParcel, notificationState);
    });
  };

  static pushNotificationHandler = (serverParcel, notificationState) => {
    const typeOfAction = serverParcel.typeEnum;
    switch(typeOfAction){
      case "message":
        break;

      case "webnews":
        const url = serverParcel.link;
        NavigationService.navigate("FCMModal", {}); //Here is where I want the modal to popup.
        //NavigationService.navigate("InAppBrowser", {url});
        break;
    }
  }

App.js

const ModalStack = createStackNavigator(
  {
    FCMModal: FCMModal
  },
  {
    mode: 'modal',
    transparentCard: true,
    cardStyle: {
      // makes transparentCard work for android
      opacity: 1.0
    }
  }
)

    let rootStack = createStackNavigator(
      {
        main: {
          screen: BottomTabNavigator //There are four navigatorstacks with multiple screens beneath here
        },
        InAppBrowser: {
          screen: InAppBrowserStack,
          defaultNavigationOptions: {
            tabBarVisible: true
          }
        },
        FCMModal: {
          screen: ModalStack
        }
      },
      {
        initialRouteName: "main",
        headerMode: "none"
      }
    );

    const AppContainer = createAppContainer(rootStack);
    export default class App extends Component {
      render() {
        return (
          <AppContainer 
            ref={navigatorRef => {
              NavigationService.setTopLevelNavigator(navigatorRef);
            }}
          />     
        );
      }
    }

Модальный класс

import React, { Component } from 'react';
import { Modal, Text, TouchableHighlight, View } from 'react-native';

export default class FCMModal extends Component {
  state = {
    modalVisible: true,
  };

  setModalVisible(visible) {
    this.setState({modalVisible: visible});
  }

  render() {
    return (
      <View style={{width: 600, height: 400, borderWidth: 2, borderColor: 'red', opacity: 0.5}}>
        <Modal
          animationType="slide"
          transparent={true}
          visible={this.state.modalVisible}
          onRequestClose={() => {console.log("CLOSING MODAL!")}}>
          <View style={{marginTop: 22}}>
            <View>
              <Text>Hello World!</Text>

              <TouchableHighlight
                onPress={() => {
                  this.setModalVisible(false);
                }}>
                <Text>Hide Modal</Text>
              </TouchableHighlight>
            </View>
          </View>
        </Modal>
      </View>
    );
  }
}
...