Skip to content

Commit

Permalink
added callback during the feedback submission flow (#40)
Browse files Browse the repository at this point in the history
* Removed un-needed member of isSettingEnabled

* Added severarl annotations

* Added callback during the feedback submission flow
  • Loading branch information
xizzhu authored Apr 1, 2020
1 parent 528f720 commit 460fbdf
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,50 @@
package com.linkedin.android.shaky.app;

import android.app.Application;
import android.util.Log;

import androidx.annotation.NonNull;
import com.linkedin.android.shaky.EmailShakeDelegate;
import com.linkedin.android.shaky.Shaky;
import com.linkedin.android.shaky.ShakyFlowCallback;

/**
* Hello world example.
*/
public class ShakyApplication extends Application {
private static final String TAG = ShakyApplication.class.getSimpleName();

private Shaky shaky;

@Override
public void onCreate() {
super.onCreate();
shaky = Shaky.with(this, new EmailShakeDelegate("hello@world.com"));
shaky = Shaky.with(this, new EmailShakeDelegate("hello@world.com"), new ShakyFlowCallback() {
@Override
public void onShakyStarted(@ShakyFlowCallback.ShakyStartedReason int reason) {
Log.d(TAG, "onShakyStarted: " + reason);
}

@Override
public void onShakyFinished(@ShakyFinishedReason int reason) {
Log.d(TAG, "onShakyFinished: " + reason);
}

@Override
public void onUserPromptShown() {
Log.d(TAG, "onUserPromptShown");
}

@Override
public void onCollectingData() {
Log.d(TAG, "onCollectingData");
}

@Override
public void onConfiguringFeedback() {
Log.d(TAG, "onConfiguringFeedback");
}
});
}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
*/
public class EmailShakeDelegate extends ShakeDelegate {
private String[] to;
@SensitivityLevel
private int sensitivityLevel = ShakeDelegate.SENSITIVITY_MEDIUM;

public EmailShakeDelegate(@NonNull String[] to) {
Expand All @@ -44,13 +45,15 @@ public final void submit(@NonNull Activity activity, @NonNull Result result) {
}

@Override
@ShakeDelegate.SensitivityLevel
public int getSensitivityLevel() {
return sensitivityLevel;
}

/**
* Optionally override sensitivityLevel to one of ShakeDelegate.SENSITIVITY_*
*/
@Override
public void setSensitivityLevel(@ShakeDelegate.SensitivityLevel int newLevel) {
sensitivityLevel = newLevel;
}
Expand All @@ -59,6 +62,7 @@ public void setSensitivityLevel(@ShakeDelegate.SensitivityLevel int newLevel) {
* Creates the email {@link Intent} and attaches all attachments.
* Subclasses should override this method to customize the email Intent.
*/
@NonNull
public Intent onSubmit(@NonNull Result result) {
return createEmailIntent(to, result.getTitle(), result.getMessage(), result.getAttachments());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
public class FeedbackActivity extends AppCompatActivity {

static final String ACTION_END_FEEDBACK_FLOW = "EndFeedbackFlow";
static final String ACTION_ACTIVITY_CLOSED_BY_USER = "ActivityClosedByUser";

static final String SCREENSHOT_URI = "screenshotUri";
static final String MESSAGE = "message";
Expand All @@ -52,7 +53,7 @@ public class FeedbackActivity extends AppCompatActivity {
public static Intent newIntent(@NonNull Context context,
@Nullable Uri screenshotUri,
@Nullable Bundle userData,
@Nullable @MenuRes int resMenu) {
@MenuRes int resMenu) {
Intent intent = new Intent(context, FeedbackActivity.class);
intent.putExtra(SCREENSHOT_URI, screenshotUri);
intent.putExtra(USER_DATA, userData);
Expand Down Expand Up @@ -97,6 +98,14 @@ protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}

@Override
public void onBackPressed() {
Intent intent = new Intent(ACTION_ACTIVITY_CLOSED_BY_USER);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

super.onBackPressed();
}

/**
* Attaches this intent's extras to the fragment and transitions to the next fragment.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,19 @@
public class SendFeedbackDialog extends DialogFragment {

public static final String ACTION_START_FEEDBACK_FLOW = "StartFeedbackFlow";
public static final String ACTION_DIALOG_DISMISSED_BY_USER = "DialogDismissedByUser";
public static final String SHOULD_DISPLAY_SETTING_UI = "ShouldDisplaySettingUI";

private static final long DISMISS_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5);

private Handler handler;
private Runnable runnable;
private boolean isSettingEnabled;

@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

isSettingEnabled = getArguments().getBoolean(SHOULD_DISPLAY_SETTING_UI, false);

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(),
R.style.AppCompatAlertDialog);

Expand All @@ -65,8 +63,14 @@ public void onClick(DialogInterface dialog, int which) {
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
builder.setNegativeButton(R.string.shaky_dialog_negative, null);
if (isSettingEnabled) {
builder.setNegativeButton(R.string.shaky_dialog_negative, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ACTION_DIALOG_DISMISSED_BY_USER);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
if (getArguments().getBoolean(SHOULD_DISPLAY_SETTING_UI, false)) {
builder.setNeutralButton(getResources().getString(R.string.shaky_setting), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Expand Down
69 changes: 65 additions & 4 deletions shaky/src/main/java/com/linkedin/android/shaky/Shaky.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,27 @@ public class Shaky implements ShakeDetector.Listener {

private final ShakeDelegate delegate;
private final ShakeDetector shakeDetector;
@Nullable
private final ShakyFlowCallback shakyFlowCallback;

private Activity activity;
private Context appContext;
private long lastShakeTime;
private CollectDataTask collectDataTask;

Shaky(@NonNull Context context, @NonNull ShakeDelegate delegate) {
Shaky(@NonNull Context context, @NonNull ShakeDelegate delegate, @Nullable ShakyFlowCallback callback) {
appContext = context.getApplicationContext();
this.delegate = delegate;
this.shakyFlowCallback = callback;
shakeDetector = new ShakeDetector(this);

shakeDetector.setSensitivity(getDetectorSensitivityLevel());

IntentFilter filter = new IntentFilter();
filter.addAction(SendFeedbackDialog.ACTION_START_FEEDBACK_FLOW);
filter.addAction(SendFeedbackDialog.ACTION_DIALOG_DISMISSED_BY_USER);
filter.addAction(FeedbackActivity.ACTION_END_FEEDBACK_FLOW);
filter.addAction(FeedbackActivity.ACTION_ACTIVITY_CLOSED_BY_USER);
filter.addAction(ShakySettingDialog.UPDATE_SHAKY_SENSITIVITY);
LocalBroadcastManager.getInstance(appContext).registerReceiver(createReceiver(), filter);
}
Expand All @@ -82,13 +87,28 @@ public class Shaky implements ShakeDetector.Listener {
*/
@NonNull
public static Shaky with(@NonNull Application application, @NonNull ShakeDelegate delegate) {
Shaky shaky = new Shaky(application.getApplicationContext(), delegate);
return with(application, delegate, null);
}

/**
* Entry point into this API.
*
* Registers shaky to the current application.
*/
@NonNull
public static Shaky with(@NonNull Application application,
@NonNull ShakeDelegate delegate,
@Nullable ShakyFlowCallback callback) {
Shaky shaky = new Shaky(application.getApplicationContext(), delegate, callback);
LifecycleCallbacks lifecycleCallbacks = new LifecycleCallbacks(shaky);
application.registerActivityLifecycleCallbacks(lifecycleCallbacks);
return shaky;
}

public void startFeedbackFlow() {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyStarted(ShakyFlowCallback.SHAKY_STARTED_MANUALLY);
}
if (!canStartFeedbackFlow()) {
return;
}
Expand All @@ -115,6 +135,9 @@ void setActivity(@Nullable Activity activity) {

private void doStartFeedbackFlow() {
new CollectDataDialog().show(activity.getFragmentManager(), COLLECT_DATA_TAG);
if (shakyFlowCallback != null) {
shakyFlowCallback.onCollectingData();
}

collectDataTask = new CollectDataTask(activity, delegate, createCallback());
collectDataTask.execute(getScreenshotBitmap());
Expand All @@ -141,6 +164,9 @@ private void stop() {

@Override
public void hearShake() {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyStarted(ShakyFlowCallback.SHAKY_STARTED_BY_SHAKE);
}
if (shouldIgnoreShake() || !canStartFeedbackFlow()) {
return;
}
Expand All @@ -151,6 +177,9 @@ public void hearShake() {
SendFeedbackDialog sendFeedbackDialog = new SendFeedbackDialog();
sendFeedbackDialog.setArguments(arguments);
sendFeedbackDialog.show(activity.getFragmentManager(), SEND_FEEDBACK_TAG);
if (shakyFlowCallback != null) {
shakyFlowCallback.onUserPromptShown();
}
}

/**
Expand All @@ -160,6 +189,9 @@ public void hearShake() {
boolean shouldIgnoreShake() {
long now = System.currentTimeMillis();
if (now < lastShakeTime + SHAKE_COOLDOWN_MS) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_TOO_FREQUENT);
}
return true;
}
lastShakeTime = now;
Expand All @@ -171,10 +203,19 @@ boolean shouldIgnoreShake() {
*/
@VisibleForTesting
boolean canStartFeedbackFlow() {
return activity != null
&& !(activity instanceof FeedbackActivity)
if (activity == null) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_NO_RESUMED_ACTIVITY);
}
return false;
}
boolean canStart = !(activity instanceof FeedbackActivity)
&& activity.getFragmentManager().findFragmentByTag(SEND_FEEDBACK_TAG) == null
&& activity.getFragmentManager().findFragmentByTag(COLLECT_DATA_TAG) == null;
if (!canStart && shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_ALREADY_STARTED);
}
return canStart;
}

@Nullable
Expand Down Expand Up @@ -217,10 +258,21 @@ public void onReceive(Context context, Intent intent) {
if (activity != null) {
doStartFeedbackFlow();
}
} else if (SendFeedbackDialog.ACTION_DIALOG_DISMISSED_BY_USER.equals(intent.getAction())
|| FeedbackActivity.ACTION_ACTIVITY_CLOSED_BY_USER.equals(intent.getAction())) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_BY_USER);
}
} else if (FeedbackActivity.ACTION_END_FEEDBACK_FLOW.equals(intent.getAction())) {
delegate.submit(activity, unpackResult(intent));
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_SUBMITTED);
}
} else if (ShakySettingDialog.UPDATE_SHAKY_SENSITIVITY.equals(intent.getAction())) {
setSensitivity(intent.getIntExtra(ShakySettingDialog.SHAKY_NEW_SENSITIVITY, ShakeDelegate.SENSITIVITY_MEDIUM));
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_SENSITIVITY_UPDATED);
}
}
}
};
Expand All @@ -240,6 +292,11 @@ public void onDataReady(@Nullable Result result) {

if (shouldStartFeedbackActivity) {
startFeedbackActivity(result == null ? new Result() : result);
return;
}

if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_NO_RESUMED_ACTIVITY);
}
}
};
Expand All @@ -251,6 +308,10 @@ public void onDataReady(@Nullable Result result) {
private void startFeedbackActivity(@NonNull Result result) {
Intent intent = FeedbackActivity.newIntent(activity, result.getScreenshotUri(), result.getData(), delegate.resMenu);
activity.startActivity(intent);

if (shakyFlowCallback != null) {
shakyFlowCallback.onConfiguringFeedback();
}
}

private Result unpackResult(Intent intent) {
Expand Down
Loading

0 comments on commit 460fbdf

Please sign in to comment.