Skip to content

Commit

Permalink
Adds updated onReportSubmitHandler API (#30)
Browse files Browse the repository at this point in the history
* ✨ add feature where a bug report can be edited before being sent to the native side
  • Loading branch information
salmamali authored and HeshamMegid committed May 7, 2019
1 parent 5a298a1 commit 5f3b96d
Show file tree
Hide file tree
Showing 14 changed files with 555 additions and 77 deletions.
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ android {

dependencies {
implementation 'com.facebook.react:react-native:+'
api ('com.instabug.library:instabug:8.2.0'){
api ('com.instabug.library:instabug:8.2.2.1'){
exclude group: 'com.android.support:appcompat-v7'
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import android.util.Log;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
Expand Down Expand Up @@ -51,6 +52,7 @@
import com.instabug.library.visualusersteps.State;

import com.instabug.reactlibrary.utils.ArrayUtil;
import com.instabug.reactlibrary.utils.ReportUtil;
import com.instabug.reactlibrary.utils.InstabugUtil;
import com.instabug.reactlibrary.utils.MapUtil;
import com.instabug.survey.OnDismissCallback;
Expand Down Expand Up @@ -212,6 +214,7 @@ public class RNInstabugReactnativeModule extends ReactContextBaseJavaModule {
private Instabug mInstabug;
private InstabugInvocationEvent invocationEvent;
private InstabugCustomTextPlaceHolder placeHolders;
private Report currentReport;

/**
* Instantiates a new Rn instabug reactnative module.
Expand Down Expand Up @@ -452,7 +455,8 @@ public void setFileAttachment(String fileUri, String fileNameWithExtension) {
@ReactMethod
public void sendJSCrash(String exceptionObject) {
try {
sendJSCrashByReflection(exceptionObject, false);
JSONObject jsonObject = new JSONObject(exceptionObject);
sendJSCrashByReflection(jsonObject, false, null);
} catch (Exception e) {
e.printStackTrace();
}
Expand All @@ -466,7 +470,8 @@ public void sendJSCrash(String exceptionObject) {
@ReactMethod
public void sendHandledJSCrash(String exceptionObject) {
try {
sendJSCrashByReflection(exceptionObject, true);
JSONObject jsonObject = new JSONObject(exceptionObject);
sendJSCrashByReflection(jsonObject, true, null);
} catch (Exception e) {
e.printStackTrace();
}
Expand All @@ -490,23 +495,20 @@ public void setCrashReportingEnabled(boolean isEnabled) {
}
}

private void sendJSCrashByReflection(String exceptionObject, boolean isHandled) {
private void sendJSCrashByReflection(JSONObject exceptionObject, boolean isHandled, Report report) {
try {
JSONObject newJSONObject = new JSONObject(exceptionObject);
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class);
Method method = getMethod(Class.forName("com.instabug.crash.CrashReporting"), "reportException", JSONObject.class, boolean.class, Report.class);
if (method != null) {
method.invoke(null, newJSONObject, isHandled);
method.invoke(null, exceptionObject, isHandled, currentReport);
currentReport = null;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (JSONException e) {
} catch (InvocationTargetException e) {
e.printStackTrace();
}

}

/**
Expand Down Expand Up @@ -1185,25 +1187,144 @@ public void onInvoke() {
*/
@ReactMethod
public void setPreSendingHandler(final Callback preSendingHandler) {
Report.OnReportCreatedListener listener = new Report.OnReportCreatedListener() {
@Override
public void onReportCreated(Report report) {
WritableMap reportParam = Arguments.createMap();
reportParam.putArray("tagsArray", convertArrayListToWritableArray(report.getTags()));
reportParam.putArray("consoleLogs", convertArrayListToWritableArray(report.getConsoleLog()));
reportParam.putString("userData", report.getUserData());
reportParam.putMap("userAttributes", convertFromHashMapToWriteableMap(report.getUserAttributes()));
reportParam.putMap("fileAttachments", convertFromHashMapToWriteableMap(report.getFileAttachments()));
sendEvent(getReactApplicationContext(), "IBGpreSendingHandler", reportParam);
currentReport = report;
}
};

Method method = getMethod(Instabug.class, "onReportSubmitHandler_Private", Report.OnReportCreatedListener.class);
if (method != null) {
try {
method.invoke(null, listener);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

@ReactMethod
public void appendTagToReport(String tag) {
if (currentReport != null) {
currentReport.addTag(tag);
}
}

@ReactMethod
public void appendConsoleLogToReport(String consoleLog) {
if (currentReport != null) {
currentReport.appendToConsoleLogs(consoleLog);
}
}

@ReactMethod
public void setUserAttributeToReport(String key, String value) {
if (currentReport != null) {
currentReport.setUserAttribute(key, value);
}
}

@ReactMethod
public void logDebugToReport(String log) {
if (currentReport != null) {
currentReport.logDebug(log);
}
}

@ReactMethod
public void logVerboseToReport(String log) {
if (currentReport != null) {
currentReport.logVerbose(log);
}
}

@ReactMethod
public void logWarnToReport(String log) {
if (currentReport != null) {
currentReport.logWarn(log);
}
}

@ReactMethod
public void logErrorToReport(String log) {
if (currentReport != null) {
currentReport.logError(log);
}
}

@ReactMethod
public void logInfoToReport(String log) {
if (currentReport != null) {
currentReport.logInfo(log);
}
}

@ReactMethod
public void addFileAttachmentWithURLToReport(String urlString, String fileName) {
if (currentReport != null) {
Uri uri = Uri.parse(urlString);
currentReport.addFileAttachment(uri, fileName);
}
}

@ReactMethod
public void addFileAttachmentWithDataToReport(String data, String fileName) {
if (currentReport != null) {
currentReport.addFileAttachment(data.getBytes(), fileName);
}
}

@ReactMethod
public void submitReport() {
Method method = getMethod(Instabug.class, "setReport", Report.class);
if (method != null) {
try {
method.invoke(null, currentReport);
currentReport = null;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}

@ReactMethod
public void getReport(Promise promise) {
try {
Method method = getMethod(Class.forName("com.instabug.library.Instabug"), "getReport");
if (method != null) {
Report report = (Report) method.invoke(null);
WritableMap reportParam = Arguments.createMap();
reportParam.putArray("tagsArray", convertArrayListToWritableArray(report.getTags()));
reportParam.putArray("consoleLogs", ReportUtil.parseConsoleLogs(report.getConsoleLog()));
reportParam.putString("userData", report.getUserData());
reportParam.putMap("userAttributes", convertFromHashMapToWriteableMap(report.getUserAttributes()));
reportParam.putMap("fileAttachments", convertFromHashMapToWriteableMap(report.getFileAttachments()));
promise.resolve(reportParam);
currentReport = report;
}

Instabug.onReportSubmitHandler(new Report.OnReportCreatedListener() {
@Override
public void onReportCreated(Report report) {
WritableMap reportParam = Arguments.createMap();
reportParam.putArray("tagsArray", convertArrayListToWritableArray(report.getTags()));
reportParam.putArray("consoleLogs", convertArrayListToWritableArray(report.getConsoleLog()));
reportParam.putString("userData", report.getUserData());
reportParam.putMap("userAttributes", convertFromHashMapToWriteableMap(report.getUserAttributes()));
reportParam.putMap("fileAttachments", convertFromHashMapToWriteableMap(report.getFileAttachments()));
sendEvent(getReactApplicationContext(), "IBGpreSendingHandler", reportParam);
}
});
} catch (java.lang.Exception exception) {
exception.printStackTrace();
} catch (ClassNotFoundException e) {
promise.reject(e);
} catch (IllegalAccessException e) {
promise.reject(e);
} catch (InvocationTargetException e) {
promise.reject(e);
}
}


private WritableMap convertFromHashMapToWriteableMap(HashMap hashMap) {
WritableMap writableMap = new WritableNativeMap();
for(int i = 0; i < hashMap.size(); i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray;

import java.util.ArrayList;
import java.util.Map;

import org.json.JSONArray;
Expand Down Expand Up @@ -130,4 +131,15 @@ public static WritableArray toWritableArray(Object[] array) {

return writableArray;
}

public static ArrayList<String> parseReadableArrayOfStrings(ReadableArray readableArray) {
ArrayList<String> array = new ArrayList<>();
for (int i = 0; i < readableArray.size(); i++) {
ReadableType type = readableArray.getType(i);
if (type == ReadableType.String) {
array.add(readableArray.getString(i));
}
}
return array;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ public static Method getMethod(Class clazz, String methodName, Class... paramete
for (Method method : methods) {
if (method.getName().equals(methodName) && method.getParameterTypes().length ==
parameterType.length) {
for (int i = 0; i < 2; i++) {
if (parameterType.length == 0) {
method.setAccessible(true);
return method;
}
for (int i = 0; i < parameterType.length; i++) {
if (method.getParameterTypes()[i] == parameterType[i]) {
if (i == method.getParameterTypes().length - 1) {
method.setAccessible(true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.instabug.reactlibrary.utils;

import android.net.Uri;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.instabug.library.model.Report;
import com.instabug.library.model.a;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;


/**
* Created by salmaali on 8/29/18.
*/

public class ReportUtil {

public static Report createReport(ReadableArray tags, ReadableArray consoleLogs, String userData, ReadableMap userAttributes, ReadableMap fileAttachments) {
Report report = new Report();
// map tags
report.addTag(ArrayUtil.parseReadableArrayOfStrings(tags).toArray(new String[0]));

// map consoleLogs
for (int i = 0; i < consoleLogs.size(); i++) {
ReadableType type = consoleLogs.getType(i);
if (type == ReadableType.String) {
report.appendToConsoleLogs(consoleLogs.getString(i));
}
}

// map userData
report.setUserData(userData);

// map userAttributes
ReadableMapKeySetIterator userAttrIterator = userAttributes.keySetIterator();
while (userAttrIterator.hasNextKey()) {
String key = userAttrIterator.nextKey();
ReadableType type = userAttributes.getType(key);
if (type == ReadableType.String) {
report.setUserAttribute(key, userAttributes.getString(key));
}

}

// map fileAttachments
ReadableMapKeySetIterator fileAttachmentsIterator = userAttributes.keySetIterator();
while (fileAttachmentsIterator.hasNextKey()) {
String key = fileAttachmentsIterator.nextKey();
ReadableType type = fileAttachments.getType(key);
if (type == ReadableType.String) {
Uri uri = Uri.parse(key);
report.addFileAttachment(uri, fileAttachments.getString(key));
}

}

return report;
}

public static WritableArray parseConsoleLogs(ArrayList<a> consoleLogs) {
WritableArray writableArray = new WritableNativeArray();

for(int i = 0; i < consoleLogs.size(); i++) {
try {
writableArray.pushString(consoleLogs.get(i).toJson());
} catch (JSONException e) {
e.printStackTrace();
}

}

return writableArray;
}
}
15 changes: 14 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export function addFileAttachment(
fileName: string
): void;
export function show(): void;
export function onReportSubmitHandler(preSendingHandler: () => void): void;
export function onReportSubmitHandler(preSendingHandler: (presendingHandler: Report) => void): void;
export function callPrivateApi(
apiName: string,
param: any
Expand Down Expand Up @@ -344,3 +344,16 @@ export enum strings {
welcomeMessageLiveWelcomeStepTitle,
welcomeMessageLiveWelcomeStepContent
}

interface Report {
logDebug(log: string);
logVerbose(log: string);
logWarn(log: string);
logError(log: string);
logInfo(log: string);
appendTag(tag: string);
appendConsoleLog(consoleLog: string);
setUserAttribute(key: string, value: string);
addFileAttachmentWithUrl(url: string, filename: string);
addFileAttachmentWithData(data: string, filename: string);
}
Loading

0 comments on commit 5f3b96d

Please sign in to comment.