1090208b5SStanisław Chmiela package io.branch.rnbranch; 2090208b5SStanisław Chmiela 3090208b5SStanisław Chmiela import android.app.Activity; 4090208b5SStanisław Chmiela import android.content.Context; 5090208b5SStanisław Chmiela import android.content.Intent; 6090208b5SStanisław Chmiela import android.content.IntentFilter; 7090208b5SStanisław Chmiela import android.content.BroadcastReceiver; 8090208b5SStanisław Chmiela import android.net.Uri; 9ef35242dSStanisław Chmiela 10db136923SSzymon20000 import androidx.annotation.Nullable; 11db136923SSzymon20000 import androidx.localbroadcastmanager.content.LocalBroadcastManager; 12090208b5SStanisław Chmiela import android.util.Log; 13090208b5SStanisław Chmiela import android.os.Handler; 14090208b5SStanisław Chmiela 15090208b5SStanisław Chmiela import com.facebook.react.bridge.*; 16090208b5SStanisław Chmiela import com.facebook.react.bridge.Promise; 17090208b5SStanisław Chmiela import com.facebook.react.modules.core.*; 18090208b5SStanisław Chmiela import com.facebook.react.bridge.ReadableMap; 19090208b5SStanisław Chmiela 20090208b5SStanisław Chmiela import io.branch.referral.*; 21090208b5SStanisław Chmiela import io.branch.referral.Branch.BranchLinkCreateListener; 22090208b5SStanisław Chmiela import io.branch.referral.BuildConfig; 23090208b5SStanisław Chmiela import io.branch.referral.util.*; 24090208b5SStanisław Chmiela import io.branch.referral.Branch; 25090208b5SStanisław Chmiela import io.branch.indexing.*; 26090208b5SStanisław Chmiela 27090208b5SStanisław Chmiela import org.json.*; 28090208b5SStanisław Chmiela 29090208b5SStanisław Chmiela import java.text.ParseException; 30090208b5SStanisław Chmiela import java.text.SimpleDateFormat; 31090208b5SStanisław Chmiela import java.util.*; 32090208b5SStanisław Chmiela 33*de56ef51SStanisław Chmiela import javax.annotation.Nonnull; 34*de56ef51SStanisław Chmiela 35090208b5SStanisław Chmiela public class RNBranchModule extends ReactContextBaseJavaModule { 36090208b5SStanisław Chmiela public static final String REACT_CLASS = "RNBranch"; 37090208b5SStanisław Chmiela public static final String REACT_MODULE_NAME = "RNBranch"; 38090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT = "io.branch.rnbranch.RNBranchModule.onInitSessionFinished"; 39090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT_BRANCH_UNIVERSAL_OBJECT = "branch_universal_object"; 40090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT_LINK_PROPERTIES = "link_properties"; 41090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT_PARAMS = "params"; 42090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT_ERROR = "error"; 43090208b5SStanisław Chmiela public static final String NATIVE_INIT_SESSION_FINISHED_EVENT_URI = "uri"; 44ef35242dSStanisław Chmiela public static final String NATIVE_INIT_SESSION_STARTED_EVENT = "io.branch.rnbranch.RNBranchModule.onInitSessionStarted"; 45ef35242dSStanisław Chmiela public static final String NATIVE_INIT_SESSION_STARTED_EVENT_URI = "uri"; 46090208b5SStanisław Chmiela private static final String RN_INIT_SESSION_SUCCESS_EVENT = "RNBranch.initSessionSuccess"; 47090208b5SStanisław Chmiela private static final String RN_INIT_SESSION_ERROR_EVENT = "RNBranch.initSessionError"; 48ef35242dSStanisław Chmiela private static final String RN_INIT_SESSION_START_EVENT = "RNBranch.initSessionStart"; 49090208b5SStanisław Chmiela private static final String INIT_SESSION_SUCCESS = "INIT_SESSION_SUCCESS"; 50090208b5SStanisław Chmiela private static final String INIT_SESSION_ERROR = "INIT_SESSION_ERROR"; 51ef35242dSStanisław Chmiela private static final String INIT_SESSION_START = "INIT_SESSION_START"; 52090208b5SStanisław Chmiela 53090208b5SStanisław Chmiela private static final String STANDARD_EVENT_ADD_TO_CART = "STANDARD_EVENT_ADD_TO_CART"; 54090208b5SStanisław Chmiela private static final String STANDARD_EVENT_ADD_TO_WISHLIST = "STANDARD_EVENT_ADD_TO_WISHLIST"; 55090208b5SStanisław Chmiela private static final String STANDARD_EVENT_VIEW_CART = "STANDARD_EVENT_VIEW_CART"; 56090208b5SStanisław Chmiela private static final String STANDARD_EVENT_INITIATE_PURCHASE = "STANDARD_EVENT_INITIATE_PURCHASE"; 57090208b5SStanisław Chmiela private static final String STANDARD_EVENT_ADD_PAYMENT_INFO = "STANDARD_EVENT_ADD_PAYMENT_INFO"; 58090208b5SStanisław Chmiela private static final String STANDARD_EVENT_PURCHASE = "STANDARD_EVENT_PURCHASE"; 59090208b5SStanisław Chmiela private static final String STANDARD_EVENT_SPEND_CREDITS = "STANDARD_EVENT_SPEND_CREDITS"; 60ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_VIEW_AD = "STANDARD_EVENT_VIEW_AD"; 61ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_CLICK_AD = "STANDARD_EVENT_CLICK_AD"; 62090208b5SStanisław Chmiela 63090208b5SStanisław Chmiela private static final String STANDARD_EVENT_SEARCH = "STANDARD_EVENT_SEARCH"; 64090208b5SStanisław Chmiela private static final String STANDARD_EVENT_VIEW_ITEM = "STANDARD_EVENT_VIEW_ITEM"; 65090208b5SStanisław Chmiela private static final String STANDARD_EVENT_VIEW_ITEMS = "STANDARD_EVENT_VIEW_ITEMS"; 66090208b5SStanisław Chmiela private static final String STANDARD_EVENT_RATE = "STANDARD_EVENT_RATE"; 67090208b5SStanisław Chmiela private static final String STANDARD_EVENT_SHARE = "STANDARD_EVENT_SHARE"; 68090208b5SStanisław Chmiela 69090208b5SStanisław Chmiela private static final String STANDARD_EVENT_COMPLETE_REGISTRATION = "STANDARD_EVENT_COMPLETE_REGISTRATION"; 70090208b5SStanisław Chmiela private static final String STANDARD_EVENT_COMPLETE_TUTORIAL = "STANDARD_EVENT_COMPLETE_TUTORIAL"; 71090208b5SStanisław Chmiela private static final String STANDARD_EVENT_ACHIEVE_LEVEL = "STANDARD_EVENT_ACHIEVE_LEVEL"; 72090208b5SStanisław Chmiela private static final String STANDARD_EVENT_UNLOCK_ACHIEVEMENT = "STANDARD_EVENT_UNLOCK_ACHIEVEMENT"; 73ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_INVITE = "STANDARD_EVENT_INVITE"; 74ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_LOGIN = "STANDARD_EVENT_LOGIN"; 75ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_RESERVE = "STANDARD_EVENT_RESERVE"; 76ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_SUBSCRIBE = "STANDARD_EVENT_SUBSCRIBE"; 77ef35242dSStanisław Chmiela private static final String STANDARD_EVENT_START_TRIAL = "STANDARD_EVENT_START_TRIAL"; 78090208b5SStanisław Chmiela 79090208b5SStanisław Chmiela private static final String IDENT_FIELD_NAME = "ident"; 80090208b5SStanisław Chmiela public static final String UNIVERSAL_OBJECT_NOT_FOUND_ERROR_CODE = "RNBranch::Error::BUONotFound"; 81000da56bSStanisław Chmiela public static final String GENERIC_ERROR = "RNBranch::Error"; 82090208b5SStanisław Chmiela private static final long AGING_HASH_TTL = 3600000; 83ef35242dSStanisław Chmiela private static final String PLUGIN_NAME = "ReactNative"; 84090208b5SStanisław Chmiela 85090208b5SStanisław Chmiela private static JSONObject initSessionResult = null; 86ef35242dSStanisław Chmiela private BroadcastReceiver mInitSessionFinishedEventReceiver = null; 87ef35242dSStanisław Chmiela private BroadcastReceiver mInitSessionStartedEventReceiver = null; 88090208b5SStanisław Chmiela private static Branch.BranchUniversalReferralInitListener initListener = null; 89090208b5SStanisław Chmiela 90090208b5SStanisław Chmiela private static Activity mActivity = null; 91090208b5SStanisław Chmiela private static boolean mUseDebug = false; 92090208b5SStanisław Chmiela private static boolean mInitialized = false; 93*de56ef51SStanisław Chmiela private static volatile boolean mNewIntent = true; 94090208b5SStanisław Chmiela private static JSONObject mRequestMetadata = new JSONObject(); 95090208b5SStanisław Chmiela 96090208b5SStanisław Chmiela private AgingHash<String, BranchUniversalObject> mUniversalObjectMap = new AgingHash<>(AGING_HASH_TTL); 97090208b5SStanisław Chmiela 98000da56bSStanisław Chmiela private static Branch.BranchReferralInitListener referralInitListener = null; 99000da56bSStanisław Chmiela getAutoInstance(Context context)100090208b5SStanisław Chmiela public static void getAutoInstance(Context context) { 101090208b5SStanisław Chmiela RNBranchConfig config = new RNBranchConfig(context); 102090208b5SStanisław Chmiela String branchKey = config.getBranchKey(); 103090208b5SStanisław Chmiela String liveKey = config.getLiveKey(); 104090208b5SStanisław Chmiela String testKey = config.getTestKey(); 105090208b5SStanisław Chmiela boolean useTest = config.getUseTestInstance(); 106090208b5SStanisław Chmiela 107ef35242dSStanisław Chmiela Branch.registerPlugin(PLUGIN_NAME, expo.modules.branch.BuildConfig.RNBRANCH_VERSION); 108ef35242dSStanisław Chmiela 109090208b5SStanisław Chmiela if (branchKey != null) { 110090208b5SStanisław Chmiela Branch.getAutoInstance(context, branchKey); 111090208b5SStanisław Chmiela } 112090208b5SStanisław Chmiela else if (useTest && testKey != null) { 113090208b5SStanisław Chmiela Branch.getAutoInstance(context, testKey); 114090208b5SStanisław Chmiela } 115090208b5SStanisław Chmiela else if (!useTest && liveKey != null) { 116090208b5SStanisław Chmiela Branch.getAutoInstance(context, liveKey); 117090208b5SStanisław Chmiela } 118090208b5SStanisław Chmiela else { 119090208b5SStanisław Chmiela Branch.getAutoInstance(context); 120090208b5SStanisław Chmiela } 121090208b5SStanisław Chmiela } 122090208b5SStanisław Chmiela reInitSession(Activity reactActivity)123000da56bSStanisław Chmiela public static void reInitSession(Activity reactActivity) { 124000da56bSStanisław Chmiela Branch branch = Branch.getInstance(); 125ef35242dSStanisław Chmiela Intent intent = reactActivity.getIntent(); 126ef35242dSStanisław Chmiela if (intent != null) { 127ef35242dSStanisław Chmiela intent.putExtra("branch_force_new_session", true); 128ef35242dSStanisław Chmiela notifyJSOfInitSessionStart(reactActivity, intent.getData()); 129ef35242dSStanisław Chmiela Branch.sessionBuilder(reactActivity).withCallback(referralInitListener).reInit(); 130ef35242dSStanisław Chmiela } else { 131ef35242dSStanisław Chmiela Log.w(REACT_CLASS, "reInitSession was called but the Intent is null"); 132ef35242dSStanisław Chmiela } 133000da56bSStanisław Chmiela } 134000da56bSStanisław Chmiela initSession(final Uri uri, Activity reactActivity, Branch.BranchUniversalReferralInitListener anInitListener)135090208b5SStanisław Chmiela public static void initSession(final Uri uri, Activity reactActivity, Branch.BranchUniversalReferralInitListener anInitListener) { 136090208b5SStanisław Chmiela initListener = anInitListener; 137090208b5SStanisław Chmiela initSession(uri, reactActivity); 138090208b5SStanisław Chmiela } 139090208b5SStanisław Chmiela initSession(final Uri uri, Activity reactActivity)140090208b5SStanisław Chmiela public static void initSession(final Uri uri, Activity reactActivity) { 141090208b5SStanisław Chmiela Branch branch = setupBranch(reactActivity.getApplicationContext()); 142090208b5SStanisław Chmiela 143090208b5SStanisław Chmiela mActivity = reactActivity; 144*de56ef51SStanisław Chmiela final boolean isNewIntent = mNewIntent; 145000da56bSStanisław Chmiela referralInitListener = new Branch.BranchReferralInitListener(){ 146090208b5SStanisław Chmiela 147090208b5SStanisław Chmiela private Activity mmActivity = null; 148090208b5SStanisław Chmiela 149090208b5SStanisław Chmiela @Override 150090208b5SStanisław Chmiela public void onInitFinished(JSONObject referringParams, BranchError error) { 151ef35242dSStanisław Chmiela // react native currently expects this to never be null 152ef35242dSStanisław Chmiela if (referringParams == null) { 153ef35242dSStanisław Chmiela referringParams = new JSONObject(); 154ef35242dSStanisław Chmiela } 155090208b5SStanisław Chmiela 156090208b5SStanisław Chmiela Log.d(REACT_CLASS, "onInitFinished"); 157090208b5SStanisław Chmiela JSONObject result = new JSONObject(); 158ef35242dSStanisław Chmiela 159090208b5SStanisław Chmiela try { 160090208b5SStanisław Chmiela result.put(NATIVE_INIT_SESSION_FINISHED_EVENT_PARAMS, referringParams); 161090208b5SStanisław Chmiela result.put(NATIVE_INIT_SESSION_FINISHED_EVENT_ERROR, error != null ? error.getMessage() : JSONObject.NULL); 162*de56ef51SStanisław Chmiela result.put(NATIVE_INIT_SESSION_FINISHED_EVENT_URI, isNewIntent && uri != null ? uri.toString() : JSONObject.NULL); 163ef35242dSStanisław Chmiela } 164ef35242dSStanisław Chmiela catch (JSONException e) { 165ef35242dSStanisław Chmiela 166090208b5SStanisław Chmiela } 167090208b5SStanisław Chmiela initSessionResult = result; 168090208b5SStanisław Chmiela 169090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject = BranchUniversalObject.getReferredBranchUniversalObject(); 170090208b5SStanisław Chmiela LinkProperties linkProperties = LinkProperties.getReferredLinkProperties(); 171090208b5SStanisław Chmiela 172090208b5SStanisław Chmiela if (initListener != null) { 173090208b5SStanisław Chmiela initListener.onInitFinished(branchUniversalObject, linkProperties, error); 174090208b5SStanisław Chmiela } 175ef35242dSStanisław Chmiela generateLocalBroadcast(referringParams, uri, branchUniversalObject, linkProperties, error); 176090208b5SStanisław Chmiela } 177090208b5SStanisław Chmiela 178090208b5SStanisław Chmiela private Branch.BranchReferralInitListener init(Activity activity) { 179090208b5SStanisław Chmiela mmActivity = activity; 180090208b5SStanisław Chmiela return this; 181090208b5SStanisław Chmiela } 182090208b5SStanisław Chmiela 183090208b5SStanisław Chmiela private void generateLocalBroadcast(JSONObject referringParams, 184090208b5SStanisław Chmiela Uri uri, 185090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject, 186090208b5SStanisław Chmiela LinkProperties linkProperties, 187090208b5SStanisław Chmiela BranchError error) { 188090208b5SStanisław Chmiela Intent broadcastIntent = new Intent(NATIVE_INIT_SESSION_FINISHED_EVENT); 189090208b5SStanisław Chmiela 190090208b5SStanisław Chmiela if (referringParams != null) { 191090208b5SStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_FINISHED_EVENT_PARAMS, referringParams.toString()); 192090208b5SStanisław Chmiela } 193090208b5SStanisław Chmiela 194090208b5SStanisław Chmiela if (branchUniversalObject != null) { 195090208b5SStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_FINISHED_EVENT_BRANCH_UNIVERSAL_OBJECT, branchUniversalObject); 196090208b5SStanisław Chmiela } 197090208b5SStanisław Chmiela 198090208b5SStanisław Chmiela if (linkProperties != null) { 199090208b5SStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_FINISHED_EVENT_LINK_PROPERTIES, linkProperties); 200090208b5SStanisław Chmiela } 201090208b5SStanisław Chmiela 202*de56ef51SStanisław Chmiela /* 203*de56ef51SStanisław Chmiela * isNewIntent is a capture of the value of mNewIntent above, so does not change when 204*de56ef51SStanisław Chmiela * mNewIntent changes in onNewIntent. 205*de56ef51SStanisław Chmiela */ 206*de56ef51SStanisław Chmiela if (isNewIntent && uri != null) { 207090208b5SStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_FINISHED_EVENT_URI, uri.toString()); 208090208b5SStanisław Chmiela } 209090208b5SStanisław Chmiela 210090208b5SStanisław Chmiela if (error != null) { 211090208b5SStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_FINISHED_EVENT_ERROR, error.getMessage()); 212090208b5SStanisław Chmiela } 213090208b5SStanisław Chmiela 214090208b5SStanisław Chmiela LocalBroadcastManager.getInstance(mmActivity).sendBroadcast(broadcastIntent); 215090208b5SStanisław Chmiela } 216000da56bSStanisław Chmiela }.init(reactActivity); 217000da56bSStanisław Chmiela 218ef35242dSStanisław Chmiela notifyJSOfInitSessionStart(reactActivity, uri); 219ef35242dSStanisław Chmiela Branch.sessionBuilder(reactActivity).withCallback(referralInitListener).withData(uri).init(); 220ef35242dSStanisław Chmiela } 221ef35242dSStanisław Chmiela 222ef35242dSStanisław Chmiela /** 223*de56ef51SStanisław Chmiela * Call from Activity.onNewIntent: 224*de56ef51SStanisław Chmiela * @Override 225*de56ef51SStanisław Chmiela * public void onNewIntent(Intent intent) { 226*de56ef51SStanisław Chmiela * super.onNewIntent(intent); 227*de56ef51SStanisław Chmiela * RNBranchModule.onNewIntent(intent); 228*de56ef51SStanisław Chmiela * } 229*de56ef51SStanisław Chmiela * @param intent the new Intent received via Activity.onNewIntent 230*de56ef51SStanisław Chmiela */ onNewIntent(@onnull Intent intent)231*de56ef51SStanisław Chmiela public static void onNewIntent(@Nonnull Intent intent) { 232*de56ef51SStanisław Chmiela mActivity.setIntent(intent); 233*de56ef51SStanisław Chmiela mNewIntent = true; 234*de56ef51SStanisław Chmiela reInitSession(mActivity); 235*de56ef51SStanisław Chmiela } 236*de56ef51SStanisław Chmiela 237*de56ef51SStanisław Chmiela /** 238ef35242dSStanisław Chmiela * Notify JavaScript of init session start. This generates an RNBranch.initSessionStart 239ef35242dSStanisław Chmiela * event to JS via the RN native event emitter. 240ef35242dSStanisław Chmiela * @param context a Context for the LocalBroadcastManager 241ef35242dSStanisław Chmiela * @param uri the URI to include in the notification or null 242ef35242dSStanisław Chmiela */ notifyJSOfInitSessionStart(Context context, Uri uri)243ef35242dSStanisław Chmiela private static void notifyJSOfInitSessionStart(Context context, Uri uri) { 244*de56ef51SStanisław Chmiela /* 245*de56ef51SStanisław Chmiela * This check just ensures that we only generate one RNBranch.initSessionStart 246*de56ef51SStanisław Chmiela * event per call to onNewIntent(). 247*de56ef51SStanisław Chmiela */ 248*de56ef51SStanisław Chmiela if (!mNewIntent) return; 249*de56ef51SStanisław Chmiela mNewIntent = false; 250*de56ef51SStanisław Chmiela 251ef35242dSStanisław Chmiela Intent broadcastIntent = new Intent(NATIVE_INIT_SESSION_STARTED_EVENT); 252ef35242dSStanisław Chmiela if (uri != null) { 253ef35242dSStanisław Chmiela broadcastIntent.putExtra(NATIVE_INIT_SESSION_STARTED_EVENT_URI, uri); 254ef35242dSStanisław Chmiela } 255ef35242dSStanisław Chmiela 256ef35242dSStanisław Chmiela LocalBroadcastManager.getInstance(context).sendBroadcast(broadcastIntent); 257ef35242dSStanisław Chmiela Log.d(REACT_CLASS, "Sent session start broadcast for " + uri); 258090208b5SStanisław Chmiela } 259090208b5SStanisław Chmiela setDebug()260090208b5SStanisław Chmiela public static void setDebug() { 261090208b5SStanisław Chmiela mUseDebug = true; 262090208b5SStanisław Chmiela } 263090208b5SStanisław Chmiela setRequestMetadata(String key, String val)264090208b5SStanisław Chmiela public static void setRequestMetadata(String key, String val) { 265090208b5SStanisław Chmiela if (key == null) { 266090208b5SStanisław Chmiela return; 267090208b5SStanisław Chmiela } 268090208b5SStanisław Chmiela 269090208b5SStanisław Chmiela if (mRequestMetadata.has(key) && val == null) { 270090208b5SStanisław Chmiela mRequestMetadata.remove(key); 271090208b5SStanisław Chmiela } 272090208b5SStanisław Chmiela 273090208b5SStanisław Chmiela try { 274090208b5SStanisław Chmiela mRequestMetadata.put(key, val); 275090208b5SStanisław Chmiela } catch (JSONException e) { 276090208b5SStanisław Chmiela // no-op 277090208b5SStanisław Chmiela } 278090208b5SStanisław Chmiela } 279090208b5SStanisław Chmiela RNBranchModule(ReactApplicationContext reactContext)280090208b5SStanisław Chmiela public RNBranchModule(ReactApplicationContext reactContext) { 281090208b5SStanisław Chmiela super(reactContext); 282ef35242dSStanisław Chmiela listenForInitSessionEventsToReactNative(reactContext); 283090208b5SStanisław Chmiela } 284090208b5SStanisław Chmiela 285090208b5SStanisław Chmiela @javax.annotation.Nullable 286090208b5SStanisław Chmiela @Override getConstants()287090208b5SStanisław Chmiela public Map<String, Object> getConstants() { 288090208b5SStanisław Chmiela final Map<String, Object> constants = new HashMap<>(); 289090208b5SStanisław Chmiela // RN events transmitted to JS 290090208b5SStanisław Chmiela 291090208b5SStanisław Chmiela constants.put(INIT_SESSION_SUCCESS, RN_INIT_SESSION_SUCCESS_EVENT); 292090208b5SStanisław Chmiela constants.put(INIT_SESSION_ERROR, RN_INIT_SESSION_ERROR_EVENT); 293ef35242dSStanisław Chmiela constants.put(INIT_SESSION_START, RN_INIT_SESSION_START_EVENT); 294090208b5SStanisław Chmiela 295090208b5SStanisław Chmiela // constants for use with BranchEvent 296090208b5SStanisław Chmiela 297090208b5SStanisław Chmiela // Commerce events 298090208b5SStanisław Chmiela 299090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_ADD_TO_CART, BRANCH_STANDARD_EVENT.ADD_TO_CART.getName()); 300090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_ADD_TO_WISHLIST, BRANCH_STANDARD_EVENT.ADD_TO_WISHLIST.getName()); 301090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_VIEW_CART, BRANCH_STANDARD_EVENT.VIEW_CART.getName()); 302090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_INITIATE_PURCHASE, BRANCH_STANDARD_EVENT.INITIATE_PURCHASE.getName()); 303090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_ADD_PAYMENT_INFO, BRANCH_STANDARD_EVENT.ADD_PAYMENT_INFO.getName()); 304090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_PURCHASE, BRANCH_STANDARD_EVENT.PURCHASE.getName()); 305090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_SPEND_CREDITS, BRANCH_STANDARD_EVENT.SPEND_CREDITS.getName()); 306ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_VIEW_AD, BRANCH_STANDARD_EVENT.VIEW_AD.getName()); 307ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_CLICK_AD, BRANCH_STANDARD_EVENT.CLICK_AD.getName()); 308090208b5SStanisław Chmiela 309090208b5SStanisław Chmiela // Content Events 310090208b5SStanisław Chmiela 311090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_SEARCH, BRANCH_STANDARD_EVENT.SEARCH.getName()); 312090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_VIEW_ITEM, BRANCH_STANDARD_EVENT.VIEW_ITEM.getName()); 313090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_VIEW_ITEMS , BRANCH_STANDARD_EVENT.VIEW_ITEMS.getName()); 314090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_RATE, BRANCH_STANDARD_EVENT.RATE.getName()); 315090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_SHARE, BRANCH_STANDARD_EVENT.SHARE.getName()); 316090208b5SStanisław Chmiela 317090208b5SStanisław Chmiela // User Lifecycle Events 318090208b5SStanisław Chmiela 319090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_COMPLETE_REGISTRATION, BRANCH_STANDARD_EVENT.COMPLETE_REGISTRATION.getName()); 320090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_COMPLETE_TUTORIAL , BRANCH_STANDARD_EVENT.COMPLETE_TUTORIAL.getName()); 321090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_ACHIEVE_LEVEL, BRANCH_STANDARD_EVENT.ACHIEVE_LEVEL.getName()); 322090208b5SStanisław Chmiela constants.put(STANDARD_EVENT_UNLOCK_ACHIEVEMENT, BRANCH_STANDARD_EVENT.UNLOCK_ACHIEVEMENT.getName()); 323ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_INVITE, BRANCH_STANDARD_EVENT.INVITE.getName()); 324ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_LOGIN , BRANCH_STANDARD_EVENT.LOGIN.getName()); 325ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_RESERVE, BRANCH_STANDARD_EVENT.RESERVE.getName()); 326ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_SUBSCRIBE, BRANCH_STANDARD_EVENT.SUBSCRIBE.getName()); 327ef35242dSStanisław Chmiela constants.put(STANDARD_EVENT_START_TRIAL, BRANCH_STANDARD_EVENT.START_TRIAL.getName()); 328090208b5SStanisław Chmiela 329090208b5SStanisław Chmiela return constants; 330090208b5SStanisław Chmiela } 331090208b5SStanisław Chmiela listenForInitSessionEventsToReactNative(ReactApplicationContext reactContext)332ef35242dSStanisław Chmiela private void listenForInitSessionEventsToReactNative(ReactApplicationContext reactContext) { 333ef35242dSStanisław Chmiela mInitSessionFinishedEventReceiver = new BroadcastReceiver() { 334090208b5SStanisław Chmiela RNBranchModule mBranchModule; 335090208b5SStanisław Chmiela 336090208b5SStanisław Chmiela @Override 337090208b5SStanisław Chmiela public void onReceive(Context context, Intent intent) { 338090208b5SStanisław Chmiela final boolean hasError = (initSessionResult.has("error") && !initSessionResult.isNull("error")); 339090208b5SStanisław Chmiela final String eventName = hasError ? RN_INIT_SESSION_ERROR_EVENT : RN_INIT_SESSION_SUCCESS_EVENT; 340090208b5SStanisław Chmiela mBranchModule.sendRNEvent(eventName, convertJsonToMap(initSessionResult)); 341090208b5SStanisław Chmiela } 342090208b5SStanisław Chmiela 343090208b5SStanisław Chmiela private BroadcastReceiver init(RNBranchModule branchModule) { 344090208b5SStanisław Chmiela mBranchModule = branchModule; 345090208b5SStanisław Chmiela return this; 346090208b5SStanisław Chmiela } 347090208b5SStanisław Chmiela }.init(this); 348090208b5SStanisław Chmiela 349ef35242dSStanisław Chmiela LocalBroadcastManager.getInstance(reactContext).registerReceiver(mInitSessionFinishedEventReceiver, new IntentFilter(NATIVE_INIT_SESSION_FINISHED_EVENT)); 350ef35242dSStanisław Chmiela 351ef35242dSStanisław Chmiela mInitSessionStartedEventReceiver = new BroadcastReceiver() { 352ef35242dSStanisław Chmiela RNBranchModule mBranchModule; 353ef35242dSStanisław Chmiela 354ef35242dSStanisław Chmiela @Override 355ef35242dSStanisław Chmiela public void onReceive(Context context, Intent intent) { 356ef35242dSStanisław Chmiela Uri uri = intent.getParcelableExtra(NATIVE_INIT_SESSION_STARTED_EVENT_URI); 357ef35242dSStanisław Chmiela WritableMap payload = new WritableNativeMap(); 358ef35242dSStanisław Chmiela if (uri != null) { 359ef35242dSStanisław Chmiela payload.putString(NATIVE_INIT_SESSION_STARTED_EVENT_URI, uri.toString()); 360ef35242dSStanisław Chmiela } 361ef35242dSStanisław Chmiela else { 362ef35242dSStanisław Chmiela payload.putNull(NATIVE_INIT_SESSION_STARTED_EVENT_URI); 363ef35242dSStanisław Chmiela } 364ef35242dSStanisław Chmiela mBranchModule.sendRNEvent(RN_INIT_SESSION_START_EVENT, payload); 365ef35242dSStanisław Chmiela } 366ef35242dSStanisław Chmiela 367ef35242dSStanisław Chmiela private BroadcastReceiver init(RNBranchModule branchModule) { 368ef35242dSStanisław Chmiela mBranchModule = branchModule; 369ef35242dSStanisław Chmiela return this; 370ef35242dSStanisław Chmiela } 371ef35242dSStanisław Chmiela }.init(this); 372ef35242dSStanisław Chmiela 373ef35242dSStanisław Chmiela LocalBroadcastManager.getInstance(reactContext).registerReceiver(mInitSessionStartedEventReceiver, new IntentFilter(NATIVE_INIT_SESSION_STARTED_EVENT)); 374090208b5SStanisław Chmiela } 375090208b5SStanisław Chmiela 376090208b5SStanisław Chmiela @Override onCatalystInstanceDestroy()377090208b5SStanisław Chmiela public void onCatalystInstanceDestroy() { 378ef35242dSStanisław Chmiela LocalBroadcastManager.getInstance(getReactApplicationContext()).unregisterReceiver(mInitSessionFinishedEventReceiver); 379ef35242dSStanisław Chmiela LocalBroadcastManager.getInstance(getReactApplicationContext()).unregisterReceiver(mInitSessionStartedEventReceiver); 380090208b5SStanisław Chmiela } 381090208b5SStanisław Chmiela 382090208b5SStanisław Chmiela @Override getName()383090208b5SStanisław Chmiela public String getName() { 384090208b5SStanisław Chmiela return REACT_MODULE_NAME; 385090208b5SStanisław Chmiela } 386090208b5SStanisław Chmiela 387090208b5SStanisław Chmiela @ReactMethod disableTracking(boolean disable)388090208b5SStanisław Chmiela public void disableTracking(boolean disable) { 389090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 390090208b5SStanisław Chmiela branch.disableTracking(disable); 391090208b5SStanisław Chmiela } 392090208b5SStanisław Chmiela 393090208b5SStanisław Chmiela @ReactMethod isTrackingDisabled(Promise promise)394090208b5SStanisław Chmiela public void isTrackingDisabled(Promise promise) { 395090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 396090208b5SStanisław Chmiela promise.resolve(branch.isTrackingDisabled()); 397090208b5SStanisław Chmiela } 398090208b5SStanisław Chmiela 399090208b5SStanisław Chmiela @ReactMethod createUniversalObject(ReadableMap universalObjectMap, Promise promise)400090208b5SStanisław Chmiela public void createUniversalObject(ReadableMap universalObjectMap, Promise promise) { 401090208b5SStanisław Chmiela String ident = UUID.randomUUID().toString(); 402090208b5SStanisław Chmiela BranchUniversalObject universalObject = createBranchUniversalObject(universalObjectMap); 403090208b5SStanisław Chmiela mUniversalObjectMap.put(ident, universalObject); 404090208b5SStanisław Chmiela 405090208b5SStanisław Chmiela WritableMap response = new WritableNativeMap(); 406090208b5SStanisław Chmiela response.putString(IDENT_FIELD_NAME, ident); 407090208b5SStanisław Chmiela promise.resolve(response); 408090208b5SStanisław Chmiela } 409090208b5SStanisław Chmiela 410090208b5SStanisław Chmiela @ReactMethod releaseUniversalObject(String ident)411090208b5SStanisław Chmiela public void releaseUniversalObject(String ident) { 412090208b5SStanisław Chmiela mUniversalObjectMap.remove(ident); 413090208b5SStanisław Chmiela } 414090208b5SStanisław Chmiela 415090208b5SStanisław Chmiela @ReactMethod redeemInitSessionResult(Promise promise)416090208b5SStanisław Chmiela public void redeemInitSessionResult(Promise promise) { 417090208b5SStanisław Chmiela promise.resolve(convertJsonToMap(initSessionResult)); 418090208b5SStanisław Chmiela } 419090208b5SStanisław Chmiela 420090208b5SStanisław Chmiela @ReactMethod getLatestReferringParams(boolean synchronous, Promise promise)421090208b5SStanisław Chmiela public void getLatestReferringParams(boolean synchronous, Promise promise) { 422090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 423090208b5SStanisław Chmiela if (synchronous) 424090208b5SStanisław Chmiela promise.resolve(convertJsonToMap(branch.getLatestReferringParamsSync())); 425090208b5SStanisław Chmiela else 426090208b5SStanisław Chmiela promise.resolve(convertJsonToMap(branch.getLatestReferringParams())); 427090208b5SStanisław Chmiela } 428090208b5SStanisław Chmiela 429090208b5SStanisław Chmiela @ReactMethod getFirstReferringParams(Promise promise)430090208b5SStanisław Chmiela public void getFirstReferringParams(Promise promise) { 431090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 432090208b5SStanisław Chmiela promise.resolve(convertJsonToMap(branch.getFirstReferringParams())); 433090208b5SStanisław Chmiela } 434090208b5SStanisław Chmiela 435090208b5SStanisław Chmiela @ReactMethod setIdentity(String identity)436090208b5SStanisław Chmiela public void setIdentity(String identity) { 437090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 438090208b5SStanisław Chmiela branch.setIdentity(identity); 439090208b5SStanisław Chmiela } 440090208b5SStanisław Chmiela 441090208b5SStanisław Chmiela @ReactMethod setRequestMetadataKey(String key, String value)442ef35242dSStanisław Chmiela public void setRequestMetadataKey(String key, String value) { 443ef35242dSStanisław Chmiela // setRequestMetadata does not do what it appears to do. Call directly to the native code. 444ef35242dSStanisław Chmiela Branch branch = Branch.getInstance(); 445ef35242dSStanisław Chmiela branch.setRequestMetadata(key, value); 446ef35242dSStanisław Chmiela } 447ef35242dSStanisław Chmiela 448ef35242dSStanisław Chmiela @ReactMethod logout()449090208b5SStanisław Chmiela public void logout() { 450090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 451090208b5SStanisław Chmiela branch.logout(); 452090208b5SStanisław Chmiela } 453090208b5SStanisław Chmiela 454090208b5SStanisław Chmiela @ReactMethod logEvent(ReadableArray contentItems, String eventName, ReadableMap params, Promise promise)455090208b5SStanisław Chmiela public void logEvent(ReadableArray contentItems, String eventName, ReadableMap params, Promise promise) { 456090208b5SStanisław Chmiela List<BranchUniversalObject> buos = new ArrayList<>(); 457090208b5SStanisław Chmiela for (int i = 0; i < contentItems.size(); ++ i) { 458090208b5SStanisław Chmiela String ident = contentItems.getString(i); 459090208b5SStanisław Chmiela BranchUniversalObject universalObject = findUniversalObjectOrReject(ident, promise); 460090208b5SStanisław Chmiela if (universalObject == null) return; 461090208b5SStanisław Chmiela buos.add(universalObject); 462090208b5SStanisław Chmiela } 463090208b5SStanisław Chmiela 464090208b5SStanisław Chmiela BranchEvent event = createBranchEvent(eventName, params); 465090208b5SStanisław Chmiela event.addContentItems(buos); 466090208b5SStanisław Chmiela event.logEvent(mActivity); 467090208b5SStanisław Chmiela promise.resolve(null); 468090208b5SStanisław Chmiela } 469090208b5SStanisław Chmiela 470090208b5SStanisław Chmiela @ReactMethod userCompletedAction(String event, ReadableMap appState)471090208b5SStanisław Chmiela public void userCompletedAction(String event, ReadableMap appState) throws JSONException { 472090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 473090208b5SStanisław Chmiela branch.userCompletedAction(event, convertMapToJson(appState)); 474090208b5SStanisław Chmiela } 475090208b5SStanisław Chmiela 476090208b5SStanisław Chmiela @ReactMethod userCompletedActionOnUniversalObject(String ident, String event, ReadableMap state, Promise promise)477090208b5SStanisław Chmiela public void userCompletedActionOnUniversalObject(String ident, String event, ReadableMap state, Promise promise) { 478090208b5SStanisław Chmiela BranchUniversalObject universalObject = findUniversalObjectOrReject(ident, promise); 479090208b5SStanisław Chmiela if (universalObject == null) return; 480090208b5SStanisław Chmiela 481090208b5SStanisław Chmiela universalObject.userCompletedAction(event, convertMapToParams(state)); 482090208b5SStanisław Chmiela promise.resolve(null); 483090208b5SStanisław Chmiela } 484090208b5SStanisław Chmiela 485090208b5SStanisław Chmiela @ReactMethod sendCommerceEvent(String revenue, ReadableMap metadata, final Promise promise)486090208b5SStanisław Chmiela public void sendCommerceEvent(String revenue, ReadableMap metadata, final Promise promise) throws JSONException { 487090208b5SStanisław Chmiela Branch branch = Branch.getInstance(); 488090208b5SStanisław Chmiela 489090208b5SStanisław Chmiela CommerceEvent commerceEvent = new CommerceEvent(); 490090208b5SStanisław Chmiela commerceEvent.setRevenue(Double.parseDouble(revenue)); 491090208b5SStanisław Chmiela 492090208b5SStanisław Chmiela JSONObject jsonMetadata = null; 493090208b5SStanisław Chmiela if (metadata != null) { 494090208b5SStanisław Chmiela jsonMetadata = convertMapToJson(metadata); 495090208b5SStanisław Chmiela } 496090208b5SStanisław Chmiela 497090208b5SStanisław Chmiela branch.sendCommerceEvent(commerceEvent, jsonMetadata, null); 498090208b5SStanisław Chmiela promise.resolve(null); 499090208b5SStanisław Chmiela } 500090208b5SStanisław Chmiela 501090208b5SStanisław Chmiela @ReactMethod showShareSheet(String ident, ReadableMap shareOptionsMap, ReadableMap linkPropertiesMap, ReadableMap controlParamsMap, Promise promise)502090208b5SStanisław Chmiela public void showShareSheet(String ident, ReadableMap shareOptionsMap, ReadableMap linkPropertiesMap, ReadableMap controlParamsMap, Promise promise) { 503090208b5SStanisław Chmiela Context context = getReactApplicationContext(); 504090208b5SStanisław Chmiela 505090208b5SStanisław Chmiela Handler mainHandler = new Handler(context.getMainLooper()); 506090208b5SStanisław Chmiela 507090208b5SStanisław Chmiela Runnable myRunnable = new Runnable() { 508090208b5SStanisław Chmiela Promise mPm; 509090208b5SStanisław Chmiela Context mContext; 510090208b5SStanisław Chmiela ReadableMap shareOptionsMap, linkPropertiesMap, controlParamsMap; 511090208b5SStanisław Chmiela String ident; 512090208b5SStanisław Chmiela 513090208b5SStanisław Chmiela private Runnable init(ReadableMap _shareOptionsMap, String _ident, ReadableMap _linkPropertiesMap, ReadableMap _controlParamsMap, Promise promise, Context context) { 514090208b5SStanisław Chmiela mPm = promise; 515090208b5SStanisław Chmiela mContext = context; 516090208b5SStanisław Chmiela shareOptionsMap = _shareOptionsMap; 517090208b5SStanisław Chmiela ident = _ident; 518090208b5SStanisław Chmiela linkPropertiesMap = _linkPropertiesMap; 519090208b5SStanisław Chmiela controlParamsMap = _controlParamsMap; 520090208b5SStanisław Chmiela return this; 521090208b5SStanisław Chmiela } 522090208b5SStanisław Chmiela 523090208b5SStanisław Chmiela @Override 524090208b5SStanisław Chmiela public void run() { 525090208b5SStanisław Chmiela String messageHeader = shareOptionsMap.hasKey("messageHeader") ? shareOptionsMap.getString("messageHeader") : ""; 526090208b5SStanisław Chmiela String messageBody = shareOptionsMap.hasKey("messageBody") ? shareOptionsMap.getString("messageBody") : ""; 527090208b5SStanisław Chmiela ShareSheetStyle shareSheetStyle = new ShareSheetStyle(mContext, messageHeader, messageBody) 528090208b5SStanisław Chmiela .setCopyUrlStyle(mContext.getResources().getDrawable(android.R.drawable.ic_menu_send), "Copy", "Added to clipboard") 529090208b5SStanisław Chmiela .setMoreOptionStyle(mContext.getResources().getDrawable(android.R.drawable.ic_menu_search), "Show more") 530090208b5SStanisław Chmiela .addPreferredSharingOption(SharingHelper.SHARE_WITH.EMAIL) 531090208b5SStanisław Chmiela .addPreferredSharingOption(SharingHelper.SHARE_WITH.TWITTER) 532090208b5SStanisław Chmiela .addPreferredSharingOption(SharingHelper.SHARE_WITH.MESSAGE) 533090208b5SStanisław Chmiela .addPreferredSharingOption(SharingHelper.SHARE_WITH.FACEBOOK); 534090208b5SStanisław Chmiela 535090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject = findUniversalObjectOrReject(ident, mPm); 536090208b5SStanisław Chmiela if (branchUniversalObject == null) { 537090208b5SStanisław Chmiela return; 538090208b5SStanisław Chmiela } 539090208b5SStanisław Chmiela 540090208b5SStanisław Chmiela LinkProperties linkProperties = createLinkProperties(linkPropertiesMap, controlParamsMap); 541090208b5SStanisław Chmiela 542090208b5SStanisław Chmiela branchUniversalObject.showShareSheet( 543090208b5SStanisław Chmiela getCurrentActivity(), 544090208b5SStanisław Chmiela linkProperties, 545090208b5SStanisław Chmiela shareSheetStyle, 546090208b5SStanisław Chmiela new Branch.BranchLinkShareListener() { 547090208b5SStanisław Chmiela private Promise mPromise = null; 548090208b5SStanisław Chmiela 549090208b5SStanisław Chmiela @Override 550090208b5SStanisław Chmiela public void onShareLinkDialogLaunched() { 551090208b5SStanisław Chmiela } 552090208b5SStanisław Chmiela 553090208b5SStanisław Chmiela @Override 554090208b5SStanisław Chmiela public void onShareLinkDialogDismissed() { 555090208b5SStanisław Chmiela if(mPromise == null) { 556090208b5SStanisław Chmiela return; 557090208b5SStanisław Chmiela } 558090208b5SStanisław Chmiela 559090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 560090208b5SStanisław Chmiela map.putString("channel", null); 561090208b5SStanisław Chmiela map.putBoolean("completed", false); 562090208b5SStanisław Chmiela map.putString("error", null); 563090208b5SStanisław Chmiela mPromise.resolve(map); 564090208b5SStanisław Chmiela mPromise = null; 565090208b5SStanisław Chmiela } 566090208b5SStanisław Chmiela 567090208b5SStanisław Chmiela @Override 568090208b5SStanisław Chmiela public void onLinkShareResponse(String sharedLink, String sharedChannel, BranchError error) { 569090208b5SStanisław Chmiela if(mPromise == null) { 570090208b5SStanisław Chmiela return; 571090208b5SStanisław Chmiela } 572090208b5SStanisław Chmiela 573090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 574090208b5SStanisław Chmiela map.putString("channel", sharedChannel); 575090208b5SStanisław Chmiela map.putBoolean("completed", true); 576090208b5SStanisław Chmiela map.putString("error", (error != null ? error.getMessage() : null)); 577090208b5SStanisław Chmiela mPromise.resolve(map); 578090208b5SStanisław Chmiela mPromise = null; 579090208b5SStanisław Chmiela } 580090208b5SStanisław Chmiela @Override 581090208b5SStanisław Chmiela public void onChannelSelected(String channelName) { 582090208b5SStanisław Chmiela } 583090208b5SStanisław Chmiela 584090208b5SStanisław Chmiela private Branch.BranchLinkShareListener init(Promise promise) { 585090208b5SStanisław Chmiela mPromise = promise; 586090208b5SStanisław Chmiela return this; 587090208b5SStanisław Chmiela } 588090208b5SStanisław Chmiela }.init(mPm)); 589090208b5SStanisław Chmiela } 590090208b5SStanisław Chmiela }.init(shareOptionsMap, ident, linkPropertiesMap, controlParamsMap, promise, context); 591090208b5SStanisław Chmiela 592090208b5SStanisław Chmiela mainHandler.post(myRunnable); 593090208b5SStanisław Chmiela } 594090208b5SStanisław Chmiela 595090208b5SStanisław Chmiela @ReactMethod registerView(String ident, Promise promise)596090208b5SStanisław Chmiela public void registerView(String ident, Promise promise) { 597090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject = findUniversalObjectOrReject(ident, promise); 598090208b5SStanisław Chmiela if (branchUniversalObject == null) { 599090208b5SStanisław Chmiela return; 600090208b5SStanisław Chmiela } 601090208b5SStanisław Chmiela 602090208b5SStanisław Chmiela branchUniversalObject.registerView(); 603090208b5SStanisław Chmiela promise.resolve(null); 604090208b5SStanisław Chmiela } 605090208b5SStanisław Chmiela 606090208b5SStanisław Chmiela @ReactMethod generateShortUrl(String ident, ReadableMap linkPropertiesMap, ReadableMap controlParamsMap, final Promise promise)607090208b5SStanisław Chmiela public void generateShortUrl(String ident, ReadableMap linkPropertiesMap, ReadableMap controlParamsMap, final Promise promise) { 608090208b5SStanisław Chmiela LinkProperties linkProperties = createLinkProperties(linkPropertiesMap, controlParamsMap); 609090208b5SStanisław Chmiela 610090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject = findUniversalObjectOrReject(ident, promise); 611090208b5SStanisław Chmiela if (branchUniversalObject == null) { 612090208b5SStanisław Chmiela return; 613090208b5SStanisław Chmiela } 614090208b5SStanisław Chmiela 615090208b5SStanisław Chmiela branchUniversalObject.generateShortUrl(mActivity, linkProperties, new BranchLinkCreateListener() { 616090208b5SStanisław Chmiela @Override 617090208b5SStanisław Chmiela public void onLinkCreate(String url, BranchError error) { 618090208b5SStanisław Chmiela Log.d(REACT_CLASS, "onLinkCreate " + url); 619090208b5SStanisław Chmiela if (error != null) { 620090208b5SStanisław Chmiela if (error.getErrorCode() == BranchError.ERR_BRANCH_DUPLICATE_URL) { 621090208b5SStanisław Chmiela promise.reject("RNBranch::Error::DuplicateResourceError", error.getMessage()); 622090208b5SStanisław Chmiela } 623090208b5SStanisław Chmiela else { 624000da56bSStanisław Chmiela promise.reject(GENERIC_ERROR, error.getMessage()); 625090208b5SStanisław Chmiela } 626090208b5SStanisław Chmiela return; 627090208b5SStanisław Chmiela } 628090208b5SStanisław Chmiela 629090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 630090208b5SStanisław Chmiela map.putString("url", url); 631090208b5SStanisław Chmiela promise.resolve(map); 632090208b5SStanisław Chmiela } 633090208b5SStanisław Chmiela }); 634090208b5SStanisław Chmiela } 635090208b5SStanisław Chmiela 636090208b5SStanisław Chmiela @ReactMethod openURL(String url, ReadableMap options)637090208b5SStanisław Chmiela public void openURL(String url, ReadableMap options) { 638090208b5SStanisław Chmiela if (mActivity == null) { 639090208b5SStanisław Chmiela // initSession is called before JS loads. This probably indicates failure to call initSession 640090208b5SStanisław Chmiela // in an activity. 641090208b5SStanisław Chmiela Log.e(REACT_CLASS, "Branch native Android SDK not initialized in openURL"); 642090208b5SStanisław Chmiela return; 643090208b5SStanisław Chmiela } 644090208b5SStanisław Chmiela 645*de56ef51SStanisław Chmiela /* 646*de56ef51SStanisław Chmiela * Using Intent.ACTION_VIEW here will open a browser for non-Branch links unless the 647*de56ef51SStanisław Chmiela * domain is registered in an intent-filter in the manifest. Instead specify the host 648*de56ef51SStanisław Chmiela * Activity. 649*de56ef51SStanisław Chmiela */ 650090208b5SStanisław Chmiela Intent intent = new Intent(mActivity, mActivity.getClass()); 651*de56ef51SStanisław Chmiela intent.setData(Uri.parse(url)); 652090208b5SStanisław Chmiela intent.putExtra("branch_force_new_session", true); 653090208b5SStanisław Chmiela 654090208b5SStanisław Chmiela mActivity.startActivity(intent); 655090208b5SStanisław Chmiela } 656090208b5SStanisław Chmiela createBranchEvent(String eventName, ReadableMap params)657090208b5SStanisław Chmiela public static BranchEvent createBranchEvent(String eventName, ReadableMap params) { 658090208b5SStanisław Chmiela BranchEvent event; 659090208b5SStanisław Chmiela try { 660090208b5SStanisław Chmiela BRANCH_STANDARD_EVENT standardEvent = BRANCH_STANDARD_EVENT.valueOf(eventName); 661090208b5SStanisław Chmiela // valueOf on BRANCH_STANDARD_EVENT Enum has succeeded, so this is a standard event. 662090208b5SStanisław Chmiela event = new BranchEvent(standardEvent); 663090208b5SStanisław Chmiela } catch (IllegalArgumentException e) { 664090208b5SStanisław Chmiela // The event name is not found in standard events. 665090208b5SStanisław Chmiela // So use custom event mode. 666090208b5SStanisław Chmiela event = new BranchEvent(eventName); 667090208b5SStanisław Chmiela } 668090208b5SStanisław Chmiela 669090208b5SStanisław Chmiela if (params.hasKey("currency")) { 670090208b5SStanisław Chmiela String currencyString = params.getString("currency"); 671090208b5SStanisław Chmiela CurrencyType currency = CurrencyType.getValue(currencyString); 672090208b5SStanisław Chmiela if (currency != null) { 673090208b5SStanisław Chmiela event.setCurrency(currency); 674090208b5SStanisław Chmiela } 675090208b5SStanisław Chmiela else { 676090208b5SStanisław Chmiela Log.w(REACT_CLASS, "Invalid currency " + currencyString); 677090208b5SStanisław Chmiela } 678090208b5SStanisław Chmiela } 679090208b5SStanisław Chmiela 680090208b5SStanisław Chmiela if (params.hasKey("transactionID")) event.setTransactionID(params.getString("transactionID")); 681090208b5SStanisław Chmiela if (params.hasKey("revenue")) event.setRevenue(Double.parseDouble(params.getString("revenue"))); 682090208b5SStanisław Chmiela if (params.hasKey("shipping")) event.setShipping(Double.parseDouble(params.getString("shipping"))); 683090208b5SStanisław Chmiela if (params.hasKey("tax")) event.setTax(Double.parseDouble(params.getString("tax"))); 684090208b5SStanisław Chmiela if (params.hasKey("coupon")) event.setCoupon(params.getString("coupon")); 685090208b5SStanisław Chmiela if (params.hasKey("affiliation")) event.setAffiliation(params.getString("affiliation")); 686090208b5SStanisław Chmiela if (params.hasKey("description")) event.setDescription(params.getString("description")); 687090208b5SStanisław Chmiela if (params.hasKey("searchQuery")) event.setSearchQuery(params.getString("searchQuery")); 688ef35242dSStanisław Chmiela if (params.hasKey("alias")) event.setCustomerEventAlias(params.getString("alias")); 689090208b5SStanisław Chmiela 690090208b5SStanisław Chmiela if (params.hasKey("customData")) { 691090208b5SStanisław Chmiela ReadableMap customData = params.getMap("customData"); 692090208b5SStanisław Chmiela ReadableMapKeySetIterator it = customData.keySetIterator(); 693090208b5SStanisław Chmiela while (it.hasNextKey()) { 694090208b5SStanisław Chmiela String key = it.nextKey(); 695090208b5SStanisław Chmiela event.addCustomDataProperty(key, customData.getString(key)); 696090208b5SStanisław Chmiela } 697090208b5SStanisław Chmiela } 698090208b5SStanisław Chmiela 699090208b5SStanisław Chmiela return event; 700090208b5SStanisław Chmiela } 701090208b5SStanisław Chmiela createLinkProperties(ReadableMap linkPropertiesMap, @Nullable ReadableMap controlParams)702090208b5SStanisław Chmiela public static LinkProperties createLinkProperties(ReadableMap linkPropertiesMap, @Nullable ReadableMap controlParams){ 703090208b5SStanisław Chmiela LinkProperties linkProperties = new LinkProperties(); 704090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("alias")) linkProperties.setAlias(linkPropertiesMap.getString("alias")); 705090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("campaign")) linkProperties.setCampaign(linkPropertiesMap.getString("campaign")); 706090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("channel")) linkProperties.setChannel(linkPropertiesMap.getString("channel")); 707090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("feature")) linkProperties.setFeature(linkPropertiesMap.getString("feature")); 708090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("stage")) linkProperties.setStage(linkPropertiesMap.getString("stage")); 709090208b5SStanisław Chmiela 710090208b5SStanisław Chmiela if (linkPropertiesMap.hasKey("tags")) { 711090208b5SStanisław Chmiela ReadableArray tags = linkPropertiesMap.getArray("tags"); 712090208b5SStanisław Chmiela for (int i=0; i<tags.size(); ++i) { 713090208b5SStanisław Chmiela String tag = tags.getString(i); 714090208b5SStanisław Chmiela linkProperties.addTag(tag); 715090208b5SStanisław Chmiela } 716090208b5SStanisław Chmiela } 717090208b5SStanisław Chmiela 718090208b5SStanisław Chmiela if (controlParams != null) { 719090208b5SStanisław Chmiela ReadableMapKeySetIterator iterator = controlParams.keySetIterator(); 720090208b5SStanisław Chmiela while (iterator.hasNextKey()) { 721090208b5SStanisław Chmiela String key = iterator.nextKey(); 722090208b5SStanisław Chmiela Object value = getReadableMapObjectForKey(controlParams, key); 723090208b5SStanisław Chmiela linkProperties.addControlParameter(key, value.toString()); 724090208b5SStanisław Chmiela } 725090208b5SStanisław Chmiela } 726090208b5SStanisław Chmiela 727090208b5SStanisław Chmiela return linkProperties; 728090208b5SStanisław Chmiela } 729090208b5SStanisław Chmiela setupBranch(Context context)730090208b5SStanisław Chmiela private static Branch setupBranch(Context context) { 731090208b5SStanisław Chmiela Branch branch = Branch.getInstance(context); 732090208b5SStanisław Chmiela 733090208b5SStanisław Chmiela if (!mInitialized) { 734090208b5SStanisław Chmiela Log.i(REACT_CLASS, "Initializing Branch SDK v. " + BuildConfig.VERSION_NAME); 735090208b5SStanisław Chmiela 736090208b5SStanisław Chmiela RNBranchConfig config = new RNBranchConfig(context); 737090208b5SStanisław Chmiela 738090208b5SStanisław Chmiela if (mUseDebug || config.getDebugMode()) branch.setDebug(); 739090208b5SStanisław Chmiela 740ef35242dSStanisław Chmiela if (config.getEnableFacebookLinkCheck()) branch.enableFacebookAppLinkCheck(); 741ef35242dSStanisław Chmiela 742090208b5SStanisław Chmiela if (mRequestMetadata != null) { 743090208b5SStanisław Chmiela Iterator keys = mRequestMetadata.keys(); 744090208b5SStanisław Chmiela while (keys.hasNext()) { 745090208b5SStanisław Chmiela String key = (String) keys.next(); 746090208b5SStanisław Chmiela try { 747090208b5SStanisław Chmiela branch.setRequestMetadata(key, mRequestMetadata.getString(key)); 748090208b5SStanisław Chmiela } catch (JSONException e) { 749090208b5SStanisław Chmiela // no-op 750090208b5SStanisław Chmiela } 751090208b5SStanisław Chmiela } 752090208b5SStanisław Chmiela } 753090208b5SStanisław Chmiela 754090208b5SStanisław Chmiela mInitialized = true; 755090208b5SStanisław Chmiela } 756090208b5SStanisław Chmiela 757090208b5SStanisław Chmiela return branch; 758090208b5SStanisław Chmiela } 759090208b5SStanisław Chmiela findUniversalObjectOrReject(final String ident, final Promise promise)760090208b5SStanisław Chmiela private BranchUniversalObject findUniversalObjectOrReject(final String ident, final Promise promise) { 761090208b5SStanisław Chmiela BranchUniversalObject universalObject = mUniversalObjectMap.get(ident); 762090208b5SStanisław Chmiela 763090208b5SStanisław Chmiela if (universalObject == null) { 764090208b5SStanisław Chmiela final String errorMessage = "BranchUniversalObject not found for ident " + ident + "."; 765090208b5SStanisław Chmiela promise.reject(UNIVERSAL_OBJECT_NOT_FOUND_ERROR_CODE, errorMessage); 766090208b5SStanisław Chmiela } 767090208b5SStanisław Chmiela 768090208b5SStanisław Chmiela return universalObject; 769090208b5SStanisław Chmiela } 770090208b5SStanisław Chmiela createContentMetadata(ReadableMap map)771090208b5SStanisław Chmiela public ContentMetadata createContentMetadata(ReadableMap map) { 772090208b5SStanisław Chmiela ContentMetadata metadata = new ContentMetadata(); 773090208b5SStanisław Chmiela 774090208b5SStanisław Chmiela if (map.hasKey("contentSchema")) { 775090208b5SStanisław Chmiela BranchContentSchema schema = BranchContentSchema.valueOf(map.getString("contentSchema")); 776090208b5SStanisław Chmiela metadata.setContentSchema(schema); 777090208b5SStanisław Chmiela } 778090208b5SStanisław Chmiela 779090208b5SStanisław Chmiela if (map.hasKey("quantity")) { 780090208b5SStanisław Chmiela metadata.setQuantity(map.getDouble("quantity")); 781090208b5SStanisław Chmiela } 782090208b5SStanisław Chmiela 783090208b5SStanisław Chmiela if (map.hasKey("price")) { 784090208b5SStanisław Chmiela double price = Double.parseDouble(map.getString("price")); 785090208b5SStanisław Chmiela CurrencyType currency = null; 786090208b5SStanisław Chmiela if (map.hasKey("currency")) currency = CurrencyType.valueOf(map.getString("currency")); 787090208b5SStanisław Chmiela metadata.setPrice(price, currency); 788090208b5SStanisław Chmiela } 789090208b5SStanisław Chmiela 790090208b5SStanisław Chmiela if (map.hasKey("sku")) { 791090208b5SStanisław Chmiela metadata.setSku(map.getString("sku")); 792090208b5SStanisław Chmiela } 793090208b5SStanisław Chmiela 794090208b5SStanisław Chmiela if (map.hasKey("productName")) { 795090208b5SStanisław Chmiela metadata.setProductName(map.getString("productName")); 796090208b5SStanisław Chmiela } 797090208b5SStanisław Chmiela 798090208b5SStanisław Chmiela if (map.hasKey("productBrand")) { 799090208b5SStanisław Chmiela metadata.setProductBrand(map.getString("productBrand")); 800090208b5SStanisław Chmiela } 801090208b5SStanisław Chmiela 802090208b5SStanisław Chmiela if (map.hasKey("productCategory")) { 803090208b5SStanisław Chmiela ProductCategory category = getProductCategory(map.getString("productCategory")); 804090208b5SStanisław Chmiela if (category != null) metadata.setProductCategory(category); 805090208b5SStanisław Chmiela } 806090208b5SStanisław Chmiela 807090208b5SStanisław Chmiela if (map.hasKey("productVariant")) { 808090208b5SStanisław Chmiela metadata.setProductVariant(map.getString("productVariant")); 809090208b5SStanisław Chmiela } 810090208b5SStanisław Chmiela 811090208b5SStanisław Chmiela if (map.hasKey("condition")) { 812090208b5SStanisław Chmiela ContentMetadata.CONDITION condition = ContentMetadata.CONDITION.valueOf(map.getString("condition")); 813090208b5SStanisław Chmiela metadata.setProductCondition(condition); 814090208b5SStanisław Chmiela } 815090208b5SStanisław Chmiela 816090208b5SStanisław Chmiela if (map.hasKey("ratingAverage") || map.hasKey("ratingMax") || map.hasKey("ratingCount")) { 817090208b5SStanisław Chmiela Double average = null, max = null; 818090208b5SStanisław Chmiela Integer count = null; 819090208b5SStanisław Chmiela if (map.hasKey("ratingAverage")) average = map.getDouble("ratingAverage"); 820090208b5SStanisław Chmiela if (map.hasKey("ratingCount")) count = map.getInt("ratingCount"); 821090208b5SStanisław Chmiela if (map.hasKey("ratingMax")) max = map.getDouble("ratingMax"); 822090208b5SStanisław Chmiela metadata.setRating(average, max, count); 823090208b5SStanisław Chmiela } 824090208b5SStanisław Chmiela 825090208b5SStanisław Chmiela if (map.hasKey("addressStreet") || 826090208b5SStanisław Chmiela map.hasKey("addressCity") || 827090208b5SStanisław Chmiela map.hasKey("addressRegion") || 828090208b5SStanisław Chmiela map.hasKey("addressCountry") || 829090208b5SStanisław Chmiela map.hasKey("addressPostalCode")) { 830090208b5SStanisław Chmiela String street = null, city = null, region = null, country = null, postalCode = null; 831090208b5SStanisław Chmiela if (map.hasKey("addressStreet")) street = map.getString("addressStreet"); 832090208b5SStanisław Chmiela if (map.hasKey("addressCity")) street = map.getString("addressCity"); 833090208b5SStanisław Chmiela if (map.hasKey("addressRegion")) street = map.getString("addressRegion"); 834090208b5SStanisław Chmiela if (map.hasKey("addressCountry")) street = map.getString("addressCountry"); 835090208b5SStanisław Chmiela if (map.hasKey("addressPostalCode")) street = map.getString("addressPostalCode"); 836090208b5SStanisław Chmiela metadata.setAddress(street, city, region, country, postalCode); 837090208b5SStanisław Chmiela } 838090208b5SStanisław Chmiela 839090208b5SStanisław Chmiela if (map.hasKey("latitude") || map.hasKey("longitude")) { 840090208b5SStanisław Chmiela Double latitude = null, longitude = null; 841090208b5SStanisław Chmiela if (map.hasKey("latitude")) latitude = map.getDouble("latitude"); 842090208b5SStanisław Chmiela if (map.hasKey("longitude")) longitude = map.getDouble("longitude"); 843090208b5SStanisław Chmiela metadata.setLocation(latitude, longitude); 844090208b5SStanisław Chmiela } 845090208b5SStanisław Chmiela 846090208b5SStanisław Chmiela if (map.hasKey("imageCaptions")) { 847090208b5SStanisław Chmiela ReadableArray captions = map.getArray("imageCaptions"); 848090208b5SStanisław Chmiela for (int j=0; j < captions.size(); ++j) { 849090208b5SStanisław Chmiela metadata.addImageCaptions(captions.getString(j)); 850090208b5SStanisław Chmiela } 851090208b5SStanisław Chmiela } 852090208b5SStanisław Chmiela 853090208b5SStanisław Chmiela if (map.hasKey("customMetadata")) { 854090208b5SStanisław Chmiela ReadableMap customMetadata = map.getMap("customMetadata"); 855090208b5SStanisław Chmiela ReadableMapKeySetIterator it = customMetadata.keySetIterator(); 856090208b5SStanisław Chmiela while (it.hasNextKey()) { 857090208b5SStanisław Chmiela String key = it.nextKey(); 858090208b5SStanisław Chmiela metadata.addCustomMetadata(key, customMetadata.getString(key)); 859090208b5SStanisław Chmiela } 860090208b5SStanisław Chmiela } 861090208b5SStanisław Chmiela 862090208b5SStanisław Chmiela return metadata; 863090208b5SStanisław Chmiela } 864090208b5SStanisław Chmiela createBranchUniversalObject(ReadableMap branchUniversalObjectMap)865090208b5SStanisław Chmiela public BranchUniversalObject createBranchUniversalObject(ReadableMap branchUniversalObjectMap) { 866090208b5SStanisław Chmiela BranchUniversalObject branchUniversalObject = new BranchUniversalObject() 867090208b5SStanisław Chmiela .setCanonicalIdentifier(branchUniversalObjectMap.getString("canonicalIdentifier")); 868090208b5SStanisław Chmiela 869090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("title")) branchUniversalObject.setTitle(branchUniversalObjectMap.getString("title")); 870090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("canonicalUrl")) branchUniversalObject.setCanonicalUrl(branchUniversalObjectMap.getString("canonicalUrl")); 871090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("contentDescription")) branchUniversalObject.setContentDescription(branchUniversalObjectMap.getString("contentDescription")); 872090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("contentImageUrl")) branchUniversalObject.setContentImageUrl(branchUniversalObjectMap.getString("contentImageUrl")); 873090208b5SStanisław Chmiela 874090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("locallyIndex")) { 875090208b5SStanisław Chmiela if (branchUniversalObjectMap.getBoolean("locallyIndex")) { 876090208b5SStanisław Chmiela branchUniversalObject.setLocalIndexMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC); 877090208b5SStanisław Chmiela } 878090208b5SStanisław Chmiela else { 879090208b5SStanisław Chmiela branchUniversalObject.setLocalIndexMode(BranchUniversalObject.CONTENT_INDEX_MODE.PRIVATE); 880090208b5SStanisław Chmiela } 881090208b5SStanisław Chmiela } 882090208b5SStanisław Chmiela 883090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("publiclyIndex")) { 884090208b5SStanisław Chmiela if (branchUniversalObjectMap.getBoolean("publiclyIndex")) { 885090208b5SStanisław Chmiela branchUniversalObject.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC); 886090208b5SStanisław Chmiela } 887090208b5SStanisław Chmiela else { 888090208b5SStanisław Chmiela branchUniversalObject.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PRIVATE); 889090208b5SStanisław Chmiela } 890090208b5SStanisław Chmiela } 891090208b5SStanisław Chmiela 892090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("contentIndexingMode")) { 893090208b5SStanisław Chmiela switch (branchUniversalObjectMap.getType("contentIndexingMode")) { 894090208b5SStanisław Chmiela case String: 895090208b5SStanisław Chmiela String mode = branchUniversalObjectMap.getString("contentIndexingMode"); 896090208b5SStanisław Chmiela 897090208b5SStanisław Chmiela if (mode.equals("private")) 898090208b5SStanisław Chmiela branchUniversalObject.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PRIVATE); 899090208b5SStanisław Chmiela else if (mode.equals("public")) 900090208b5SStanisław Chmiela branchUniversalObject.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC); 901090208b5SStanisław Chmiela else 902090208b5SStanisław Chmiela Log.w(REACT_CLASS, "Unsupported value for contentIndexingMode: " + mode + 903090208b5SStanisław Chmiela ". Supported values are \"public\" and \"private\""); 904090208b5SStanisław Chmiela break; 905090208b5SStanisław Chmiela default: 906090208b5SStanisław Chmiela Log.w(REACT_CLASS, "contentIndexingMode must be a String"); 907090208b5SStanisław Chmiela break; 908090208b5SStanisław Chmiela } 909090208b5SStanisław Chmiela } 910090208b5SStanisław Chmiela 911090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("currency") && branchUniversalObjectMap.hasKey("price")) { 912090208b5SStanisław Chmiela String currencyString = branchUniversalObjectMap.getString("currency"); 913090208b5SStanisław Chmiela CurrencyType currency = CurrencyType.valueOf(currencyString); 914090208b5SStanisław Chmiela branchUniversalObject.setPrice(branchUniversalObjectMap.getDouble("price"), currency); 915090208b5SStanisław Chmiela } 916090208b5SStanisław Chmiela 917090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("expirationDate")) { 918090208b5SStanisław Chmiela String expirationString = branchUniversalObjectMap.getString("expirationDate"); 919090208b5SStanisław Chmiela SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); 920090208b5SStanisław Chmiela format.setTimeZone(TimeZone.getTimeZone("UTC")); 921090208b5SStanisław Chmiela try { 922090208b5SStanisław Chmiela Date date = format.parse(expirationString); 923090208b5SStanisław Chmiela Log.d(REACT_CLASS, "Expiration date is " + date.toString()); 924090208b5SStanisław Chmiela branchUniversalObject.setContentExpiration(date); 925090208b5SStanisław Chmiela } 926090208b5SStanisław Chmiela catch (ParseException e) { 927090208b5SStanisław Chmiela Log.w(REACT_CLASS, "Invalid expiration date format. Valid format is YYYY-mm-ddTHH:MM:SS, e.g. 2017-02-01T00:00:00. All times UTC."); 928090208b5SStanisław Chmiela } 929090208b5SStanisław Chmiela } 930090208b5SStanisław Chmiela 931090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("keywords")) { 932090208b5SStanisław Chmiela ReadableArray keywords = branchUniversalObjectMap.getArray("keywords"); 933090208b5SStanisław Chmiela for (int i=0; i<keywords.size(); ++i) { 934090208b5SStanisław Chmiela branchUniversalObject.addKeyWord(keywords.getString(i)); 935090208b5SStanisław Chmiela } 936090208b5SStanisław Chmiela } 937090208b5SStanisław Chmiela 938090208b5SStanisław Chmiela if(branchUniversalObjectMap.hasKey("metadata")) { 939090208b5SStanisław Chmiela ReadableMap metadataMap = branchUniversalObjectMap.getMap("metadata"); 940090208b5SStanisław Chmiela ReadableMapKeySetIterator iterator = metadataMap.keySetIterator(); 941090208b5SStanisław Chmiela while (iterator.hasNextKey()) { 942090208b5SStanisław Chmiela String metadataKey = iterator.nextKey(); 943090208b5SStanisław Chmiela Object metadataObject = getReadableMapObjectForKey(metadataMap, metadataKey); 944090208b5SStanisław Chmiela branchUniversalObject.addContentMetadata(metadataKey, metadataObject.toString()); 945090208b5SStanisław Chmiela HashMap<String, String> metadata = branchUniversalObject.getMetadata(); 946090208b5SStanisław Chmiela } 947090208b5SStanisław Chmiela } 948090208b5SStanisław Chmiela 949090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("type")) branchUniversalObject.setContentType(branchUniversalObjectMap.getString("type")); 950090208b5SStanisław Chmiela 951090208b5SStanisław Chmiela if (branchUniversalObjectMap.hasKey("contentMetadata")) { 952090208b5SStanisław Chmiela branchUniversalObject.setContentMetadata(createContentMetadata(branchUniversalObjectMap.getMap("contentMetadata"))); 953090208b5SStanisław Chmiela } 954090208b5SStanisław Chmiela 955090208b5SStanisław Chmiela return branchUniversalObject; 956090208b5SStanisław Chmiela } 957090208b5SStanisław Chmiela 958090208b5SStanisław Chmiela @Nullable getProductCategory(final String stringValue)959090208b5SStanisław Chmiela public ProductCategory getProductCategory(final String stringValue) { 960090208b5SStanisław Chmiela ProductCategory[] possibleValues = ProductCategory.class.getEnumConstants(); 961090208b5SStanisław Chmiela for (ProductCategory value: possibleValues) { 962090208b5SStanisław Chmiela if (stringValue.equals(value.getName())) { 963090208b5SStanisław Chmiela return value; 964090208b5SStanisław Chmiela } 965090208b5SStanisław Chmiela } 966090208b5SStanisław Chmiela Log.w(REACT_CLASS, "Could not find product category " + stringValue); 967090208b5SStanisław Chmiela return null; 968090208b5SStanisław Chmiela } 969090208b5SStanisław Chmiela 970090208b5SStanisław Chmiela @ReactMethod redeemRewards(int value, String bucket, Promise promise)971090208b5SStanisław Chmiela public void redeemRewards(int value, String bucket, Promise promise) 972090208b5SStanisław Chmiela { 973090208b5SStanisław Chmiela if (bucket == null) { 974090208b5SStanisław Chmiela Branch.getInstance().redeemRewards(value, new RedeemRewardsListener(promise)); 975090208b5SStanisław Chmiela } else { 976090208b5SStanisław Chmiela Branch.getInstance().redeemRewards(bucket, value, new RedeemRewardsListener(promise)); 977090208b5SStanisław Chmiela } 978090208b5SStanisław Chmiela } 979090208b5SStanisław Chmiela 980090208b5SStanisław Chmiela @ReactMethod loadRewards(String bucket, Promise promise)981090208b5SStanisław Chmiela public void loadRewards(String bucket, Promise promise) 982090208b5SStanisław Chmiela { 983090208b5SStanisław Chmiela Branch.getInstance().loadRewards(new LoadRewardsListener(bucket, promise)); 984090208b5SStanisław Chmiela } 985090208b5SStanisław Chmiela 986090208b5SStanisław Chmiela @ReactMethod getCreditHistory(Promise promise)987090208b5SStanisław Chmiela public void getCreditHistory(Promise promise) 988090208b5SStanisław Chmiela { 989090208b5SStanisław Chmiela Branch.getInstance().getCreditHistory(new CreditHistoryListener(promise)); 990090208b5SStanisław Chmiela } 991090208b5SStanisław Chmiela 992090208b5SStanisław Chmiela protected class CreditHistoryListener implements Branch.BranchListResponseListener 993090208b5SStanisław Chmiela { 994090208b5SStanisław Chmiela private Promise _promise; 995090208b5SStanisław Chmiela 996090208b5SStanisław Chmiela // Constructor that takes in a required callbackContext object CreditHistoryListener(Promise promise)997090208b5SStanisław Chmiela public CreditHistoryListener(Promise promise) { 998090208b5SStanisław Chmiela this._promise = promise; 999090208b5SStanisław Chmiela } 1000090208b5SStanisław Chmiela 1001090208b5SStanisław Chmiela // Listener that implements BranchListResponseListener for getCreditHistory() 1002090208b5SStanisław Chmiela @Override onReceivingResponse(JSONArray list, BranchError error)1003090208b5SStanisław Chmiela public void onReceivingResponse(JSONArray list, BranchError error) { 1004090208b5SStanisław Chmiela ArrayList<String> errors = new ArrayList<String>(); 1005090208b5SStanisław Chmiela if (error == null) { 1006090208b5SStanisław Chmiela try { 1007090208b5SStanisław Chmiela ReadableArray result = convertJsonToArray(list); 1008090208b5SStanisław Chmiela this._promise.resolve(result); 1009090208b5SStanisław Chmiela } catch (JSONException err) { 1010000da56bSStanisław Chmiela this._promise.reject(GENERIC_ERROR, err.getMessage()); 1011090208b5SStanisław Chmiela } 1012090208b5SStanisław Chmiela } else { 1013090208b5SStanisław Chmiela String errorMessage = error.getMessage(); 1014090208b5SStanisław Chmiela Log.d(REACT_CLASS, errorMessage); 1015000da56bSStanisław Chmiela this._promise.reject(GENERIC_ERROR, errorMessage); 1016090208b5SStanisław Chmiela } 1017090208b5SStanisław Chmiela } 1018090208b5SStanisław Chmiela } 1019090208b5SStanisław Chmiela 1020090208b5SStanisław Chmiela protected class RedeemRewardsListener implements Branch.BranchReferralStateChangedListener 1021090208b5SStanisław Chmiela { 1022090208b5SStanisław Chmiela private Promise _promise; 1023090208b5SStanisław Chmiela RedeemRewardsListener(Promise promise)1024090208b5SStanisław Chmiela public RedeemRewardsListener(Promise promise) { 1025090208b5SStanisław Chmiela this._promise = promise; 1026090208b5SStanisław Chmiela } 1027090208b5SStanisław Chmiela 1028090208b5SStanisław Chmiela @Override onStateChanged(boolean changed, BranchError error)1029090208b5SStanisław Chmiela public void onStateChanged(boolean changed, BranchError error) { 1030090208b5SStanisław Chmiela if (error == null) { 1031090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 1032090208b5SStanisław Chmiela map.putBoolean("changed", changed); 1033090208b5SStanisław Chmiela this._promise.resolve(map); 1034090208b5SStanisław Chmiela } else { 1035090208b5SStanisław Chmiela String errorMessage = error.getMessage(); 1036090208b5SStanisław Chmiela Log.d(REACT_CLASS, errorMessage); 1037000da56bSStanisław Chmiela this._promise.reject(GENERIC_ERROR, errorMessage); 1038090208b5SStanisław Chmiela } 1039090208b5SStanisław Chmiela } 1040090208b5SStanisław Chmiela } 1041090208b5SStanisław Chmiela 1042090208b5SStanisław Chmiela protected class LoadRewardsListener implements Branch.BranchReferralStateChangedListener 1043090208b5SStanisław Chmiela { 1044090208b5SStanisław Chmiela private String _bucket; 1045090208b5SStanisław Chmiela private Promise _promise; 1046090208b5SStanisław Chmiela LoadRewardsListener(String bucket, Promise promise)1047090208b5SStanisław Chmiela public LoadRewardsListener(String bucket, Promise promise) { 1048090208b5SStanisław Chmiela this._bucket = bucket; 1049090208b5SStanisław Chmiela this._promise = promise; 1050090208b5SStanisław Chmiela } 1051090208b5SStanisław Chmiela 1052090208b5SStanisław Chmiela @Override onStateChanged(boolean changed, BranchError error)1053090208b5SStanisław Chmiela public void onStateChanged(boolean changed, BranchError error) { 1054090208b5SStanisław Chmiela if (error == null) { 1055090208b5SStanisław Chmiela int credits = 0; 1056090208b5SStanisław Chmiela if (this._bucket == null) { 1057090208b5SStanisław Chmiela credits = Branch.getInstance().getCredits(); 1058090208b5SStanisław Chmiela } else { 1059090208b5SStanisław Chmiela credits = Branch.getInstance().getCreditsForBucket(this._bucket); 1060090208b5SStanisław Chmiela } 1061090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 1062090208b5SStanisław Chmiela map.putInt("credits", credits); 1063090208b5SStanisław Chmiela this._promise.resolve(map); 1064090208b5SStanisław Chmiela } else { 1065090208b5SStanisław Chmiela String errorMessage = error.getMessage(); 1066090208b5SStanisław Chmiela Log.d(REACT_CLASS, errorMessage); 1067000da56bSStanisław Chmiela this._promise.reject(GENERIC_ERROR, errorMessage); 1068090208b5SStanisław Chmiela } 1069090208b5SStanisław Chmiela } 1070090208b5SStanisław Chmiela } 1071090208b5SStanisław Chmiela sendRNEvent(String eventName, @Nullable WritableMap params)1072090208b5SStanisław Chmiela public void sendRNEvent(String eventName, @Nullable WritableMap params) { 1073090208b5SStanisław Chmiela // This should avoid the crash in getJSModule() at startup 1074090208b5SStanisław Chmiela // See also: https://github.com/walmartreact/react-native-orientation-listener/issues/8 1075090208b5SStanisław Chmiela 1076090208b5SStanisław Chmiela ReactApplicationContext context = getReactApplicationContext(); 1077090208b5SStanisław Chmiela Handler mainHandler = new Handler(context.getMainLooper()); 1078090208b5SStanisław Chmiela 1079090208b5SStanisław Chmiela Runnable poller = new Runnable() { 1080090208b5SStanisław Chmiela 1081090208b5SStanisław Chmiela private Runnable init(ReactApplicationContext _context, Handler _mainHandler, String _eventName, WritableMap _params) { 1082090208b5SStanisław Chmiela mMainHandler = _mainHandler; 1083090208b5SStanisław Chmiela mEventName = _eventName; 1084090208b5SStanisław Chmiela mContext = _context; 1085090208b5SStanisław Chmiela mParams = _params; 1086090208b5SStanisław Chmiela return this; 1087090208b5SStanisław Chmiela } 1088090208b5SStanisław Chmiela 1089090208b5SStanisław Chmiela final int pollDelayInMs = 100; 1090090208b5SStanisław Chmiela final int maxTries = 300; 1091090208b5SStanisław Chmiela 1092090208b5SStanisław Chmiela int tries = 1; 1093090208b5SStanisław Chmiela String mEventName; 1094090208b5SStanisław Chmiela WritableMap mParams; 1095090208b5SStanisław Chmiela Handler mMainHandler; 1096090208b5SStanisław Chmiela ReactApplicationContext mContext; 1097090208b5SStanisław Chmiela 1098090208b5SStanisław Chmiela @Override 1099090208b5SStanisław Chmiela public void run() { 1100090208b5SStanisław Chmiela try { 1101090208b5SStanisław Chmiela Log.d(REACT_CLASS, "Catalyst instance poller try " + Integer.toString(tries)); 1102090208b5SStanisław Chmiela if (mContext.hasActiveCatalystInstance()) { 1103090208b5SStanisław Chmiela Log.d(REACT_CLASS, "Catalyst instance active"); 1104090208b5SStanisław Chmiela mContext 1105090208b5SStanisław Chmiela .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 1106090208b5SStanisław Chmiela .emit(mEventName, mParams); 1107090208b5SStanisław Chmiela } else { 1108090208b5SStanisław Chmiela tries++; 1109090208b5SStanisław Chmiela if (tries <= maxTries) { 1110090208b5SStanisław Chmiela mMainHandler.postDelayed(this, pollDelayInMs); 1111090208b5SStanisław Chmiela } else { 1112090208b5SStanisław Chmiela Log.e(REACT_CLASS, "Could not get Catalyst instance"); 1113090208b5SStanisław Chmiela } 1114090208b5SStanisław Chmiela } 1115090208b5SStanisław Chmiela } 1116090208b5SStanisław Chmiela catch (Exception e) { 1117090208b5SStanisław Chmiela e.printStackTrace(); 1118090208b5SStanisław Chmiela } 1119090208b5SStanisław Chmiela } 1120090208b5SStanisław Chmiela }.init(context, mainHandler, eventName, params); 1121090208b5SStanisław Chmiela 1122090208b5SStanisław Chmiela Log.d(REACT_CLASS, "sendRNEvent"); 1123090208b5SStanisław Chmiela 1124090208b5SStanisław Chmiela mainHandler.post(poller); 1125090208b5SStanisław Chmiela } 1126090208b5SStanisław Chmiela getReadableMapObjectForKey(ReadableMap readableMap, String key)1127090208b5SStanisław Chmiela private static Object getReadableMapObjectForKey(ReadableMap readableMap, String key) { 1128090208b5SStanisław Chmiela switch (readableMap.getType(key)) { 1129090208b5SStanisław Chmiela case Null: 1130090208b5SStanisław Chmiela return "Null"; 1131090208b5SStanisław Chmiela case Boolean: 1132090208b5SStanisław Chmiela return readableMap.getBoolean(key); 1133090208b5SStanisław Chmiela case Number: 1134090208b5SStanisław Chmiela if (readableMap.getDouble(key) % 1 == 0) { 1135090208b5SStanisław Chmiela return readableMap.getInt(key); 1136090208b5SStanisław Chmiela } else { 1137090208b5SStanisław Chmiela return readableMap.getDouble(key); 1138090208b5SStanisław Chmiela } 1139090208b5SStanisław Chmiela case String: 1140090208b5SStanisław Chmiela return readableMap.getString(key); 1141090208b5SStanisław Chmiela default: 1142090208b5SStanisław Chmiela return "Unsupported Type"; 1143090208b5SStanisław Chmiela } 1144090208b5SStanisław Chmiela } 1145090208b5SStanisław Chmiela convertMapToJson(ReadableMap readableMap)1146090208b5SStanisław Chmiela private static JSONObject convertMapToJson(ReadableMap readableMap) throws JSONException { 1147090208b5SStanisław Chmiela JSONObject object = new JSONObject(); 1148090208b5SStanisław Chmiela ReadableMapKeySetIterator iterator = readableMap.keySetIterator(); 1149090208b5SStanisław Chmiela while (iterator.hasNextKey()) { 1150090208b5SStanisław Chmiela String key = iterator.nextKey(); 1151090208b5SStanisław Chmiela switch (readableMap.getType(key)) { 1152090208b5SStanisław Chmiela case Null: 1153090208b5SStanisław Chmiela object.put(key, JSONObject.NULL); 1154090208b5SStanisław Chmiela break; 1155090208b5SStanisław Chmiela case Boolean: 1156090208b5SStanisław Chmiela object.put(key, readableMap.getBoolean(key)); 1157090208b5SStanisław Chmiela break; 1158090208b5SStanisław Chmiela case Number: 1159090208b5SStanisław Chmiela object.put(key, readableMap.getDouble(key)); 1160090208b5SStanisław Chmiela break; 1161090208b5SStanisław Chmiela case String: 1162090208b5SStanisław Chmiela object.put(key, readableMap.getString(key)); 1163090208b5SStanisław Chmiela break; 1164090208b5SStanisław Chmiela case Map: 1165090208b5SStanisław Chmiela object.put(key, convertMapToJson(readableMap.getMap(key))); 1166090208b5SStanisław Chmiela break; 1167090208b5SStanisław Chmiela case Array: 1168090208b5SStanisław Chmiela object.put(key, convertArrayToJson(readableMap.getArray(key))); 1169090208b5SStanisław Chmiela break; 1170090208b5SStanisław Chmiela } 1171090208b5SStanisław Chmiela } 1172090208b5SStanisław Chmiela return object; 1173090208b5SStanisław Chmiela } 1174090208b5SStanisław Chmiela convertArrayToJson(ReadableArray readableArray)1175090208b5SStanisław Chmiela private static JSONArray convertArrayToJson(ReadableArray readableArray) throws JSONException { 1176090208b5SStanisław Chmiela JSONArray array = new JSONArray(); 1177090208b5SStanisław Chmiela for (int i = 0; i < readableArray.size(); i++) { 1178090208b5SStanisław Chmiela switch (readableArray.getType(i)) { 1179090208b5SStanisław Chmiela case Null: 1180090208b5SStanisław Chmiela break; 1181090208b5SStanisław Chmiela case Boolean: 1182090208b5SStanisław Chmiela array.put(readableArray.getBoolean(i)); 1183090208b5SStanisław Chmiela break; 1184090208b5SStanisław Chmiela case Number: 1185090208b5SStanisław Chmiela array.put(readableArray.getDouble(i)); 1186090208b5SStanisław Chmiela break; 1187090208b5SStanisław Chmiela case String: 1188090208b5SStanisław Chmiela array.put(readableArray.getString(i)); 1189090208b5SStanisław Chmiela break; 1190090208b5SStanisław Chmiela case Map: 1191090208b5SStanisław Chmiela array.put(convertMapToJson(readableArray.getMap(i))); 1192090208b5SStanisław Chmiela break; 1193090208b5SStanisław Chmiela case Array: 1194090208b5SStanisław Chmiela array.put(convertArrayToJson(readableArray.getArray(i))); 1195090208b5SStanisław Chmiela break; 1196090208b5SStanisław Chmiela } 1197090208b5SStanisław Chmiela } 1198090208b5SStanisław Chmiela return array; 1199090208b5SStanisław Chmiela } 1200090208b5SStanisław Chmiela convertJsonToMap(JSONObject jsonObject)1201090208b5SStanisław Chmiela private static WritableMap convertJsonToMap(JSONObject jsonObject) { 1202090208b5SStanisław Chmiela if(jsonObject == null) { 1203090208b5SStanisław Chmiela return null; 1204090208b5SStanisław Chmiela } 1205090208b5SStanisław Chmiela 1206090208b5SStanisław Chmiela WritableMap map = new WritableNativeMap(); 1207090208b5SStanisław Chmiela 1208090208b5SStanisław Chmiela try { 1209090208b5SStanisław Chmiela Iterator<String> iterator = jsonObject.keys(); 1210090208b5SStanisław Chmiela while (iterator.hasNext()) { 1211090208b5SStanisław Chmiela String key = iterator.next(); 1212090208b5SStanisław Chmiela Object value = jsonObject.get(key); 1213090208b5SStanisław Chmiela if (value instanceof JSONObject) { 1214090208b5SStanisław Chmiela map.putMap(key, convertJsonToMap((JSONObject) value)); 1215090208b5SStanisław Chmiela } else if (value instanceof JSONArray) { 1216090208b5SStanisław Chmiela map.putArray(key, convertJsonToArray((JSONArray) value)); 1217090208b5SStanisław Chmiela } else if (value instanceof Boolean) { 1218090208b5SStanisław Chmiela map.putBoolean(key, (Boolean) value); 1219090208b5SStanisław Chmiela } else if (value instanceof Integer) { 1220090208b5SStanisław Chmiela map.putInt(key, (Integer) value); 1221090208b5SStanisław Chmiela } else if (value instanceof Double) { 1222090208b5SStanisław Chmiela map.putDouble(key, (Double) value); 1223090208b5SStanisław Chmiela } else if (value instanceof String) { 1224090208b5SStanisław Chmiela map.putString(key, (String) value); 1225090208b5SStanisław Chmiela } else if (value == null || value == JSONObject.NULL) { 1226090208b5SStanisław Chmiela map.putNull(key); 1227090208b5SStanisław Chmiela } else { 1228090208b5SStanisław Chmiela map.putString(key, value.toString()); 1229090208b5SStanisław Chmiela } 1230090208b5SStanisław Chmiela } 1231090208b5SStanisław Chmiela } catch(JSONException ex) { 1232090208b5SStanisław Chmiela map.putString("error", "Failed to convert JSONObject to WriteableMap: " + ex.getMessage()); 1233090208b5SStanisław Chmiela } 1234090208b5SStanisław Chmiela 1235090208b5SStanisław Chmiela return map; 1236090208b5SStanisław Chmiela } 1237090208b5SStanisław Chmiela convertJsonToArray(JSONArray jsonArray)1238090208b5SStanisław Chmiela private static WritableArray convertJsonToArray(JSONArray jsonArray) throws JSONException { 1239090208b5SStanisław Chmiela WritableArray array = new WritableNativeArray(); 1240090208b5SStanisław Chmiela 1241090208b5SStanisław Chmiela for (int i = 0; i < jsonArray.length(); i++) { 1242090208b5SStanisław Chmiela Object value = jsonArray.get(i); 1243090208b5SStanisław Chmiela if (value instanceof JSONObject) { 1244090208b5SStanisław Chmiela array.pushMap(convertJsonToMap((JSONObject) value)); 1245090208b5SStanisław Chmiela } else if (value instanceof JSONArray) { 1246090208b5SStanisław Chmiela array.pushArray(convertJsonToArray((JSONArray) value)); 1247090208b5SStanisław Chmiela } else if (value instanceof Boolean) { 1248090208b5SStanisław Chmiela array.pushBoolean((Boolean) value); 1249090208b5SStanisław Chmiela } else if (value instanceof Integer) { 1250090208b5SStanisław Chmiela array.pushInt((Integer) value); 1251090208b5SStanisław Chmiela } else if (value instanceof Double) { 1252090208b5SStanisław Chmiela array.pushDouble((Double) value); 1253090208b5SStanisław Chmiela } else if (value instanceof String) { 1254090208b5SStanisław Chmiela array.pushString((String) value); 1255090208b5SStanisław Chmiela } else { 1256090208b5SStanisław Chmiela array.pushString(value.toString()); 1257090208b5SStanisław Chmiela } 1258090208b5SStanisław Chmiela } 1259090208b5SStanisław Chmiela return array; 1260090208b5SStanisław Chmiela } 1261090208b5SStanisław Chmiela 1262090208b5SStanisław Chmiela // Convert an arbitrary ReadableMap to a string-string hash of custom params for userCompletedAction. convertMapToParams(ReadableMap map)1263090208b5SStanisław Chmiela private static HashMap<String, String> convertMapToParams(ReadableMap map) { 1264090208b5SStanisław Chmiela if (map == null) return null; 1265090208b5SStanisław Chmiela 1266090208b5SStanisław Chmiela HashMap<String, String> hash = new HashMap<>(); 1267090208b5SStanisław Chmiela 1268090208b5SStanisław Chmiela ReadableMapKeySetIterator iterator = map.keySetIterator(); 1269090208b5SStanisław Chmiela while (iterator.hasNextKey()) { 1270090208b5SStanisław Chmiela String key = iterator.nextKey(); 1271090208b5SStanisław Chmiela switch (map.getType(key)) { 1272090208b5SStanisław Chmiela case String: 1273090208b5SStanisław Chmiela hash.put(key, map.getString(key)); 1274090208b5SStanisław Chmiela case Boolean: 1275090208b5SStanisław Chmiela hash.put(key, "" + map.getBoolean(key)); 1276090208b5SStanisław Chmiela case Number: 1277090208b5SStanisław Chmiela hash.put(key, "" + map.getDouble(key)); 1278090208b5SStanisław Chmiela default: 1279090208b5SStanisław Chmiela Log.w(REACT_CLASS, "Unsupported data type in params, ignoring"); 1280090208b5SStanisław Chmiela } 1281090208b5SStanisław Chmiela } 1282090208b5SStanisław Chmiela 1283090208b5SStanisław Chmiela return hash; 1284090208b5SStanisław Chmiela } 1285090208b5SStanisław Chmiela } 1286