Pushwoosh / pushwoosh-react-native-plugin

Other
58 stars 44 forks source link

Back press in-app #115

Closed Blerr511 closed 3 years ago

Blerr511 commented 3 years ago

Hi I'm using react-native When I receiving In-App message and pressing back button to close it also being called my application backhandler , so when I trying to close In-App message my navigator navigating back.

wfhm commented 3 years ago

Hi @Blerr511,

Could you please provide the code for how exactly you handle back button clicks in your app? So far, it looks like you are subscribed for the button pressed event, and its callback fires simultaneously with ours.

Blerr511 commented 3 years ago

I'm using something like this image I need to prevent my console log if in-app message opened

Blerr511 commented 3 years ago

Problem was not with Backhandler , also I have AppState change listener on my app and when its become focused I Navigating to back , so when In-App being closed my AppState change called , but anyway I need way to detect when In-App showed , to prevent my AppState handler work , so I find a solution with native modules , reffering on docs create rich media queue I created native module for that purpose

package com.InAppListener;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.pushwoosh.exception.PushwooshException;
import com.pushwoosh.richmedia.RichMedia;
import com.pushwoosh.richmedia.RichMediaManager;
import com.pushwoosh.richmedia.RichMediaPresentingDelegate;

import java.util.HashMap;
import java.util.Map;

public class InAppListener extends ReactContextBaseJavaModule implements RichMediaPresentingDelegate {
    static private final String JS_EVENT_RICH_MEDIA_LOAD = "onInAppLoad";
    static private final String JS_EVENT_RICH_MEDIA_OPEN = "onInAppOpen";
    static private final String JS_EVENT_RICH_MEDIA_ERROR = "onInAppError";
    static private final String JS_EVENT_RICH_MEDIA_CLOSE = "onInAppClose";
    static private final String REACT_MODULE = "InAppListener";

    private ReactApplicationContext mContext;

    @NonNull
    @Override
    public String getName() {
        return REACT_MODULE;
    }

    @Nullable
    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put("onLoad",JS_EVENT_RICH_MEDIA_LOAD);
        constants.put("onOpen",JS_EVENT_RICH_MEDIA_OPEN);
        constants.put("onError",JS_EVENT_RICH_MEDIA_ERROR);
        constants.put("onClose",JS_EVENT_RICH_MEDIA_CLOSE);
        return constants;
    }

    public InAppListener(ReactApplicationContext context) {
        super(context);
        mContext = context;
        RichMediaManager.setDelegate(this);
    }
    private void sendEvent(String eventName,
                           @Nullable WritableMap params) {
        mContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                .emit(eventName, params);
    }
    private WritableMap toMap(RichMedia richMedia)
    {
        WritableMap map = Arguments.createMap();
        map.putString("content",richMedia.getContent());
        map.putString("sourceName",richMedia.getSource().name());
        map.putInt("hasCode",richMedia.hashCode());
        map.putBoolean("isLockScreen",richMedia.isLockScreen());
        map.putBoolean("isRequired",richMedia.isRequired());
        return  map;
    }
    @Override
    public boolean shouldPresent(RichMedia richMedia) {
        sendEvent(JS_EVENT_RICH_MEDIA_LOAD,toMap(richMedia));
        return true;
    }

    @Override
    public void onPresent(RichMedia richMedia) {
        sendEvent(JS_EVENT_RICH_MEDIA_OPEN,toMap(richMedia));
    }

    @Override
    public void onError(RichMedia richMedia, PushwooshException e) {
        WritableMap map = Arguments.createMap();
        map.putString("message",e.getMessage());
        map.putString("str",e.toString());
        sendEvent(JS_EVENT_RICH_MEDIA_ERROR,map);
    }

    @Override
    public void onClose(RichMedia richMedia) {
        sendEvent(JS_EVENT_RICH_MEDIA_CLOSE,toMap(richMedia));
    }
}

this code will emit events to my JS DeviceEventEmmiter

wfhm commented 3 years ago

@Blerr511,

This is exactly what RichMediaPresentingDelegate was created for, great job here:)