Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Commit

Permalink
Merge pull request #74 from okulygin/master
Browse files Browse the repository at this point in the history
Add support for single threaded feedback, setting the user name and email.
  • Loading branch information
Benjamin Scholtysik (Reimold) committed May 4, 2017
2 parents f5d8ff7 + c05a127 commit 4ed99e0
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 20 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ The HockeyApp API is exposed to your app via the global `hockeyapp` object, whic

* [**trackEvent**](#hockeyapptrackevent) - Logs an app-specific event for analytic purposes.

* [**setUserEmail**](#hockeyappsetuseremail) - Set the users email address.

* [**setUserName**](#hockeyappsetusername) - Set the user name.

### hockeyapp.addMetaData

```javascript
Expand Down Expand Up @@ -226,6 +230,8 @@ Initializes the HockeyApp plugin, and configures it with the appropriate app ID

7. **appSecret** - The app secret as provided by the HockeyApp portal. This parameter only needs to be set if you're setting the `loginMode` parameter to `EMAIL_ONLY`.

8. **shouldCreateNewFeedbackThread** - Indicates if a new thread should be created for each new feedback message. Setting it to `true` will force a new thread whenever a new message is sent as opposed to the default resume thread behaviour.

### hockeyapp.trackEvent

```javascript
Expand All @@ -242,6 +248,40 @@ Logs an app-specific event for analytic purposes.

3. **eventName** - The name (e.g. "ITEM_ADDED") of the custom event that should be logged.

### hockeyapp.setUserEmail

```javascript
hockeyapp.setUserEmail(success, failure, userEmail)
```

#### Parameters

1. **success** - `Function` that will be triggered when the event has been successfully tracked.

2. **failure** - `Function` that will be triggered when tracking the event failed for some reason.

3. **userEmail** - The user's email address.

Right now this is used by the `BITCrashManager` to attach to a crash report.
`BITFeedbackManager` uses it too for assigning the user to a discussion thread.

### hockeyapp.setUserName

```javascript
hockeyapp.setUserName(success, failure, userName)
```

#### Parameters

1. **success** - `Function` that will be triggered when the event has been successfully tracked.

2. **failure** - `Function` that will be triggered when tracking the event failed for some reason.

3. **userName** - The user's name.

Right now this is used by the `BITCrashManager` to attach to a crash report.
`BITFeedbackManager` uses it too for assigning the user to a discussion thread.

## PhoneGap Build

This plugin is compatible with [PhoneGap Build](https://build.phonegap.com), and supports creating iOS builds out-of-the-box. However, in order to create Android builds, you need to add the following element to your app's `config.xml` file, as a child of the `<platform name="android">` element:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-hockeyapp",
"version": "2.2.3",
"version": "2.2.4",
"description": "Cordova plugin for HockeyApp",
"cordova": {
"id": "cordova-plugin-hockeyapp",
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="cordova-plugin-hockeyapp" version="2.2.3" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="cordova-plugin-hockeyapp" version="2.2.4" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>HockeyApp</name>
<description>Cordova plugin for HockeyApp</description>
<license>Apache 2.0</license>
Expand Down
33 changes: 31 additions & 2 deletions src/android/HockeyApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.FeedbackManager;
import net.hockeyapp.android.FeedbackManagerListener;
import net.hockeyapp.android.LoginManager;
import net.hockeyapp.android.LoginManagerListener;
import net.hockeyapp.android.metrics.MetricsManager;
import net.hockeyapp.android.objects.FeedbackMessage;
import net.hockeyapp.android.Tracking;
import net.hockeyapp.android.UpdateManager;

Expand Down Expand Up @@ -100,8 +102,9 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
appId = args.optString(0);
boolean autoSend = args.optBoolean(3);
boolean ignoreDefaultHandler = args.optBoolean(4, false);

FeedbackManager.register(cordova.getActivity(), appId);
boolean shouldCreateNewFeedbackThread = args.optBoolean(5, false);

FeedbackManager.register(cordova.getActivity(), appId, shouldCreateNewFeedbackThread ? new SingleThreadFeedbackManagerListener() : null);
this.crashListener = new ConfiguredCrashManagerListener(autoSend, ignoreDefaultHandler);

MetricsManager.register(cordova.getActivity(), cordova.getActivity().getApplication(), appId);
Expand Down Expand Up @@ -162,6 +165,20 @@ public void onSuccess() {
return true;
}

if (action.equals("setUserEmail")) {
String userEmail = args.optString(0);
FeedbackManager.setUserEmail(userEmail);
callbackContext.success();
return true;
}

if (action.equals("setUserName")) {
String userName = args.optString(0);
FeedbackManager.setUserName(userName);
callbackContext.success();
return true;
}

if (action.equals("feedback")) {
cordova.getActivity().runOnUiThread(new Runnable() {
@Override
Expand Down Expand Up @@ -286,6 +303,18 @@ public void onResume(boolean multitasking) {
}
}

class SingleThreadFeedbackManagerListener extends FeedbackManagerListener {
@Override
public boolean feedbackAnswered(FeedbackMessage latestMessage){
return true;
}

@Override
public boolean shouldCreateNewFeedbackThread(){
return true;
}
}

class ConfiguredCrashManagerListener extends CrashManagerListener {
private boolean autoSend = false;
private boolean ignoreDefaultHandler = false;
Expand Down
5 changes: 5 additions & 0 deletions src/ios/HockeyApp.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@

@interface HockeyApp : CDVPlugin <BITHockeyManagerDelegate> {
BOOL initialized;
BOOL shouldCreateNewFeedbackThread;
NSString *userEmail;
NSString *userName;
NSMutableDictionary *crashMetaData;
}

- (void)start:(CDVInvokedUrlCommand*)command;
- (void)setUserEmail:(CDVInvokedUrlCommand*)command;
- (void)setUserName:(CDVInvokedUrlCommand*)command;
- (void)feedback:(CDVInvokedUrlCommand*)command;
- (void)composeFeedback:(CDVInvokedUrlCommand*)command;
- (void)checkForUpdate:(CDVInvokedUrlCommand*)command;
Expand Down
64 changes: 51 additions & 13 deletions src/ios/HockeyApp.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ - (id)init
{
self = [super init];
initialized = NO;
userEmail = nil;
userName = nil;
crashMetaData = [NSMutableDictionary new];
shouldCreateNewFeedbackThread = NO;
return self;
}

Expand All @@ -22,31 +25,35 @@ - (void) start:(CDVInvokedUrlCommand*)command
} else if ([arguments count] > 1) {
NSString* token = [arguments objectAtIndex:0];
NSString* autoSend = [arguments objectAtIndex:3];

NSString* createNewFeedbackThread = [arguments objectAtIndex:5];
// no-op this for now. Appears to do nothing on ios side?
// NSString* ignoreDefaultHandler = [arguments objectAtIndex:4];

if ([autoSend boolValue] == YES) {
[[BITHockeyManager sharedHockeyManager].crashManager setCrashManagerStatus:BITCrashManagerStatusAutoSend];
[[NSUserDefaults standardUserDefaults] setInteger:BITCrashManagerStatusAutoSend forKey:@"BITCrashManagerStatus"];
}


if ([createNewFeedbackThread boolValue] == YES) {
shouldCreateNewFeedbackThread = YES;
}

[[BITHockeyManager sharedHockeyManager] configureWithIdentifier:token
delegate:self];
[[BITHockeyManager sharedHockeyManager] startManager];

// Set authentication mode prior to verifying the user
NSInteger authType = BITAuthenticatorIdentificationTypeAnonymous;
[[BITHockeyManager sharedHockeyManager].authenticator setIdentificationType:BITAuthenticatorIdentificationTypeHockeyAppUser];
if ([arguments count] >= 3) {
NSString *authTypeString = [arguments objectAtIndex:1];
authType = [authTypeString intValue];
NSString *appSecret = [arguments objectAtIndex:2];

[[BITHockeyManager sharedHockeyManager].authenticator setAuthenticationSecret:appSecret];
[[BITHockeyManager sharedHockeyManager].authenticator setIdentificationType:authType];
}

if (authType == BITAuthenticatorIdentificationTypeAnonymous) {
[[BITHockeyManager sharedHockeyManager].authenticator authenticateInstallation];
initialized = YES;
Expand All @@ -62,6 +69,21 @@ - (void) start:(CDVInvokedUrlCommand*)command
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)setUserEmail:(CDVInvokedUrlCommand*)command {
NSString* emailArgumentValue = [command argumentAtIndex:0];
userEmail = emailArgumentValue;

[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
}

- (void)setUserName:(CDVInvokedUrlCommand*)command {
NSString* nameArgumentValue = [command argumentAtIndex:0];
userName = nameArgumentValue;

[self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK] callbackId:command.callbackId];
}


- (void) feedback:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
Expand All @@ -78,22 +100,22 @@ - (void) feedback:(CDVInvokedUrlCommand*)command
- (void) composeFeedback:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;

if(initialized == YES) {
NSMutableArray* items = [NSMutableArray array];

BOOL attachScreenshot = [[command argumentAtIndex:0] boolValue];
if (attachScreenshot) {
UIImage* screenshot = [[BITHockeyManager sharedHockeyManager].feedbackManager screenshot];
[items addObject:screenshot];
}

if ([command.arguments count] > 1) {
NSString* jsonData = [command argumentAtIndex:1];
NSData* data = [jsonData dataUsingEncoding:NSUTF8StringEncoding];
[items addObject:data];
}

[[BITHockeyManager sharedHockeyManager].feedbackManager showFeedbackComposeViewWithPreparedItems:items];
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
}
Expand Down Expand Up @@ -123,7 +145,7 @@ - (void) forceCrash:(CDVInvokedUrlCommand *)command {
- (void) addMetaData:(CDVInvokedUrlCommand *)command {
NSData* arguments = [[command.arguments objectAtIndex:0] dataUsingEncoding:NSUTF8StringEncoding];
CDVPluginResult* pluginResult = nil;

if(initialized == YES) {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"crashMetaData.txt"];
Expand All @@ -149,7 +171,7 @@ - (void) addMetaData:(CDVInvokedUrlCommand *)command {
[file writeData:[crashLogString dataUsingEncoding:NSUTF8StringEncoding]];
[file closeFile];
}

pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
}
else {
Expand All @@ -173,20 +195,36 @@ - (void) trackEvent:(CDVInvokedUrlCommand *)command {
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"hockeyapp cordova plugin is not started, call hockeyapp.start(successcb, errorcb, hockeyapp_id) first!"];
}

[self.commandDelegate sendPluginResult:pluginResult
callbackId:command.callbackId];
}

#pragma mark - BITHockeyManagerDelegate

- (NSString *)userEmailForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager {
return userEmail;
}

- (NSString *)userNameForHockeyManager:(BITHockeyManager *)hockeyManager componentManager:(BITHockeyBaseManager *)componentManager {
return userName;
}

#pragma mark - BITCrashManagerDelegate

- (NSString *)applicationLogForCrashManager:(BITCrashManager *)crashManager {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:@"crashMetaData.txt"];

NSString *logData = [NSString stringWithContentsOfFile:fileName encoding:NSUTF8StringEncoding error:nil];

return logData;
}

#pragma mark - BITFeedbackManagerDelegate

- (BOOL)forceNewFeedbackThreadForFeedbackManager:(BITFeedbackManager *)feedbackManager {
return shouldCreateNewFeedbackThread;
}

@end
14 changes: 11 additions & 3 deletions www/hockeyapp.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
var exec = require('cordova/exec');

var hockeyapp = {
start: function(success, failure, appId, autoSend, ignoreDefaultHandler, loginMode, appSecret) {
start: function(success, failure, appId, autoSend, ignoreDefaultHandler, loginMode, appSecret, shouldCreateNewFeedbackThread) {
autoSend = (autoSend === true || autoSend === "true");
ignoreDefaultHandler = (ignoreDefaultHandler === true || ignoreDefaultHandler === "true");
loginMode = loginMode || hockeyapp.loginMode.ANONYMOUS;
appSecret = appSecret || '';

shouldCreateNewFeedbackThread= (shouldCreateNewFeedbackThread === true || shouldCreateNewFeedbackThread === "true");


// Requesting loginMode.EMAIL_ONLY without an appSecret is not permitted
if (loginMode === hockeyapp.loginMode.EMAIL_ONLY && appSecret.trim() === '') {
if (failure && typeof failure === 'function') {
Expand All @@ -15,7 +17,13 @@ var hockeyapp = {
return;
}

exec(success, failure, "HockeyApp", "start", [appId, loginMode, appSecret, autoSend, ignoreDefaultHandler]);
exec(success, failure, "HockeyApp", "start", [appId, loginMode, appSecret, autoSend, ignoreDefaultHandler, shouldCreateNewFeedbackThread]);
},
setUserEmail: function (success, failure, userEmail) {
exec(success, failure, "HockeyApp", "setUserEmail", [ userEmail ]);
},
setUserName: function (success, failure, userName) {
exec(success, failure, "HockeyApp", "setUserName", [ userName ]);
},
feedback: function (success, failure) {
exec(success, failure, "HockeyApp", "feedback", []);
Expand Down

0 comments on commit 4ed99e0

Please sign in to comment.