Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public Integer getPopupTheme() {
return popupTheme;
}

@Nullable
@Override
public String getSelectScreenSubtitle() {
return "Did you encounter a problem? You can turn on \"Shake to send feedback\" " +
"below and shake your device where the problem was to take a screenshot";
}
}, new ShakyFlowCallback() {
@Override
public void onShakyStarted(@ShakyFlowCallback.ShakyStartedReason int reason) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public class FeedbackActivity extends AppCompatActivity {
static final String RES_MENU = "resMenu";
static final String SUBCATEGORY = "subcategory";
static final String THEME = "theme";
static final String SELECT_SCREEN_TITLE = "selectScreenTitle";
static final String SELECT_SCREEN_SUBTITLE = "selectScreenSubtitle";
static final String SHAKE_TURNED_ON = "shakeTurnedOn";
static final String SHAKE_ENABLED = "shakeEnabled";
static final int MISSING_RESOURCE = 0;

private Uri imageUri;
Expand All @@ -59,12 +63,20 @@ public static Intent newIntent(@NonNull Context context,
@Nullable Uri screenshotUri,
@Nullable Bundle userData,
@MenuRes int resMenu,
@StyleRes int theme) {
@StyleRes int theme,
@Nullable String selectScreenTitle,
@Nullable String selectScreenSubtitle,
boolean shakeTurnedOn,
boolean shakeEnabled) {
Intent intent = new Intent(context, FeedbackActivity.class);
intent.putExtra(SCREENSHOT_URI, screenshotUri);
intent.putExtra(USER_DATA, userData);
intent.putExtra(RES_MENU, resMenu);
intent.putExtra(THEME, theme);
intent.putExtra(SELECT_SCREEN_TITLE, selectScreenTitle);
intent.putExtra(SELECT_SCREEN_SUBTITLE, selectScreenSubtitle);
intent.putExtra(SHAKE_TURNED_ON, shakeTurnedOn);
intent.putExtra(SHAKE_ENABLED, shakeEnabled);
return intent;
}

Expand All @@ -84,7 +96,13 @@ public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.add(R.id.shaky_fragment_container, SelectFragment.newInstance(customTheme))
.add(R.id.shaky_fragment_container,
SelectFragment.newInstance(
customTheme,
getIntent().getStringExtra(SELECT_SCREEN_TITLE),
getIntent().getStringExtra(SELECT_SCREEN_SUBTITLE),
getIntent().getBooleanExtra(SHAKE_TURNED_ON, false),
getIntent().getBooleanExtra(SHAKE_ENABLED, false)))
.commit();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,56 @@
*/
package com.linkedin.android.shaky;

import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.fragment.app.Fragment;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.appcompat.widget.Toolbar;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.TextView;

/**
* Kicks off the feedback flow, pretty selector to choose the type of feedback.
*/
public class SelectFragment extends Fragment {

public static final String UPDATE_SHAKE_DETECTION_STATUS = "UpdateShakeDetectionStatus";
public static final String SHAKE_TURNED_ON = "ShakeTurnedOn";

private static final String KEY_THEME = "theme";
private static final String KEY_TITLE = "title";
private static final String KEY_SUBTITLE = "subtitle";
private static final String KEY_SHAKE_TURNED_ON = "shakeTurnedOn";
private static final String KEY_SHAKE_ENABLED = "shakeEnabled";

@Nullable private LayoutInflater inflater;

@NonNull
static SelectFragment newInstance(@Nullable @StyleRes Integer theme) {
static SelectFragment newInstance(@Nullable @StyleRes Integer theme,
@Nullable String title,
@Nullable String subtitle,
boolean shakeTurnedOn,
boolean shakeEnabled) {
SelectFragment fragment = new SelectFragment();
Bundle args = new Bundle();
if (theme != null) {
args.putInt(KEY_THEME, theme);
}
args.putString(KEY_TITLE, title);
args.putString(KEY_SUBTITLE, subtitle);
args.putBoolean(KEY_SHAKE_TURNED_ON, shakeTurnedOn);
args.putBoolean(KEY_SHAKE_ENABLED, shakeEnabled);
fragment.setArguments(args);
return fragment;
}
Expand All @@ -65,6 +86,8 @@ public void onViewCreated(View view, Bundle savedInstanceState) {
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.shaky_recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(),
DividerItemDecoration.VERTICAL));

Toolbar toolbar = (Toolbar) view.findViewById(R.id.shaky_toolbar);
toolbar.setTitle(R.string.shaky_feedback_title);
Expand All @@ -75,6 +98,34 @@ public void onClick(View v) {
getActivity().onBackPressed();
}
});

TextView title = view.findViewById(R.id.shaky_select_title);
String customTitle = getArguments().getString(KEY_TITLE);
if (customTitle != null) {
title.setText(customTitle);
}

TextView subtitle = view.findViewById(R.id.shaky_select_subtitle);
String customSubtitle = getArguments().getString(KEY_SUBTITLE);
if (customSubtitle != null) {
subtitle.setText(customSubtitle);
subtitle.setVisibility(View.VISIBLE);
}

Switch shakeToggle = view.findViewById(R.id.shaky_select_shake_switch);
shakeToggle.setChecked(getArguments().getBoolean(KEY_SHAKE_TURNED_ON, false));
if (getArguments().getBoolean(KEY_SHAKE_ENABLED)) {
shakeToggle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Intent intent = new Intent(UPDATE_SHAKE_DETECTION_STATUS);
intent.putExtra(SHAKE_TURNED_ON, isChecked);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
});
} else {
shakeToggle.setVisibility(View.GONE);
}
}

@NonNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public abstract class ShakeDelegate {
@MenuRes protected int resMenu = FormFragment.DEFAULT_MENU;

/**
* @return true if shake detection should be enabled, false otherwise
* @return true if shake detection should be enabled, false otherwise. If enabled, the user can
* still turn off shaking through the UI. If disabled, UI to toggle shaking won't be shown.
*/
public boolean isEnabled() {
return true;
Expand Down Expand Up @@ -122,6 +123,22 @@ public Integer getPopupTheme() {
return null;
}

/**
* @return the title of the category select screen, or null if the default title should be shown
*/
@Nullable
public String getSelectScreenTitle() {
return null;
}

/**
* @return the subtitle of the category select screen, or null if no subtitle should be shown
*/
@Nullable
public String getSelectScreenSubtitle() {
return null;
}

/**
* Called from the background thread during the feedback collection flow. This method
* can be used to collect extra debug information to include in the feedback
Expand Down
31 changes: 29 additions & 2 deletions shaky/src/main/java/com/linkedin/android/shaky/Shaky.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.os.Bundle;
import android.view.View;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
Expand All @@ -36,6 +37,8 @@
import com.jraska.falcon.Falcon;
import com.squareup.seismic.ShakeDetector;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

Expand All @@ -48,6 +51,16 @@
*/
public class Shaky implements ShakeDetector.Listener {

public static final int SHAKE_ON = 25;
public static final int SHAKE_OFF = 26;

@IntDef({
SHAKE_ON,
SHAKE_OFF
})
@Retention(RetentionPolicy.SOURCE)
public @interface ShakeDetectionStatus {}

private static final String SEND_FEEDBACK_TAG = "SendFeedback";
private static final String COLLECT_DATA_TAG = "CollectFeedbackData";

Expand All @@ -62,6 +75,7 @@ public class Shaky implements ShakeDetector.Listener {
private Activity activity;
private Context appContext;
private long lastShakeTime;
private boolean shakeTurnedOn = true;
private CollectDataTask collectDataTask;

Shaky(@NonNull Context context, @NonNull ShakeDelegate delegate, @Nullable ShakyFlowCallback callback) {
Expand All @@ -78,6 +92,7 @@ public class Shaky implements ShakeDetector.Listener {
filter.addAction(FeedbackActivity.ACTION_END_FEEDBACK_FLOW);
filter.addAction(FeedbackActivity.ACTION_ACTIVITY_CLOSED_BY_USER);
filter.addAction(ShakySettingDialog.UPDATE_SHAKY_SENSITIVITY);
filter.addAction(SelectFragment.UPDATE_SHAKE_DETECTION_STATUS);
LocalBroadcastManager.getInstance(appContext).registerReceiver(createReceiver(), filter);
}

Expand Down Expand Up @@ -122,6 +137,10 @@ public void setSensitivity(@ShakeDelegate.SensitivityLevel int sensitivityLevel)
shakeDetector.setSensitivity(getDetectorSensitivityLevel());
}

public void setShakeStatus(@ShakeDetectionStatus int status) {
shakeTurnedOn = status == SHAKE_ON;
}

void setActivity(@Nullable Activity activity) {
this.activity = activity;
if (activity != null) {
Expand Down Expand Up @@ -193,10 +212,14 @@ public void hearShake() {
}

/**
* @return true if a shake happened in the last {@link #SHAKE_COOLDOWN_MS}, false otherwise.
* @return true if a shake happened in the last {@link #SHAKE_COOLDOWN_MS} or shake detection
* is disabled, or false otherwise
*/
@VisibleForTesting
boolean shouldIgnoreShake() {
if (!shakeTurnedOn) {
return true;
}
long now = System.currentTimeMillis();
if (now < lastShakeTime + SHAKE_COOLDOWN_MS) {
if (shakyFlowCallback != null) {
Expand Down Expand Up @@ -285,6 +308,8 @@ public void onReceive(Context context, Intent intent) {
if (shakyFlowCallback != null) {
shakyFlowCallback.onShakyFinished(ShakyFlowCallback.SHAKY_FINISHED_SENSITIVITY_UPDATED);
}
} else if (SelectFragment.UPDATE_SHAKE_DETECTION_STATUS.equals(intent.getAction())) {
shakeTurnedOn = intent.getBooleanExtra(SelectFragment.SHAKE_TURNED_ON, false);
}
}
};
Expand Down Expand Up @@ -322,7 +347,9 @@ private void startFeedbackActivity(@NonNull Result result) {
result.getScreenshotUri(),
result.getData(),
delegate.resMenu,
delegate.getTheme() != null ? delegate.getTheme() : FeedbackActivity.MISSING_RESOURCE);
delegate.getTheme() != null ? delegate.getTheme() : FeedbackActivity.MISSING_RESOURCE,
delegate.getSelectScreenTitle(),
delegate.getSelectScreenSubtitle(), true, true);
activity.startActivity(intent);

if (shakyFlowCallback != null) {
Expand Down
47 changes: 46 additions & 1 deletion shaky/src/main/res/layout/shaky_select.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,59 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/shaky_img_mobile_phone_56dp"
android:layout_gravity="center_horizontal"
android:paddingTop="16dp"/>

<TextView
android:id="@+id/shaky_select_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/shaky_feedback_title"
android:textColor="?attr/shakySelectTitleColor"
android:textSize="@dimen/shaky_row_title_textsize"
android:textStyle="bold"
android:layout_marginVertical="16dp"
android:layout_marginHorizontal="@dimen/shaky_list_margin"/>

<TextView
android:id="@+id/shaky_select_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:textColor="?attr/shakySelectSubtitleColor"
android:layout_marginBottom="16dp"
android:layout_marginHorizontal="@dimen/shaky_list_margin"
android:visibility="gone"/>

<Switch
android:id="@+id/shaky_select_shake_switch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shaky_dialog_title"
android:textColor="?attr/shakyCategoryListItemTitleColor"
android:textSize="@dimen/shaky_row_title_textsize"
android:layout_marginHorizontal="@dimen/shaky_list_margin"
android:layout_marginVertical="16dp"/>

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"
android:layout_marginHorizontal="@dimen/shaky_list_margin"/>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/shaky_recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:overScrollMode="never"
android:paddingTop="@dimen/shaky_content_top_padding"
android:layout_marginHorizontal="@dimen/shaky_list_margin"
android:scrollbars="none"/>

</LinearLayout>
7 changes: 3 additions & 4 deletions shaky/src/main/res/layout/shaky_single_row.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:padding="@dimen/shaky_button_padding">
android:orientation="horizontal">

<ImageView
android:id="@+id/shaky_row_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/shaky_icon_padding"
android:layout_marginVertical="@dimen/shaky_icon_padding"
android:layout_marginRight="@dimen/shaky_icon_padding"
android:adjustViewBounds="true"
android:gravity="center_vertical"
android:scaleType="centerInside"
Expand All @@ -45,7 +45,6 @@
android:id="@+id/shaky_row_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/shaky_row_textspacing"
android:gravity="start"
android:textAlignment="textStart"
android:text="@string/shaky_row1_title"
Expand Down
3 changes: 3 additions & 0 deletions shaky/src/main/res/values/shaky_attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@

<!-- Category Select -->
<attr name="shakySelectBackgroundColor" format="reference|color" />
<attr name="shakySelectTitleColor" format="reference|color" />
<attr name="shakySelectSubtitleColor" format="reference|color" />
<attr name="shakyCategoryListItemTitleColor" format="reference|color" />
<attr name="shakyCategoryListItemSubtitleColor" format="reference|color" />
<attr name="shakyCategoryListDividerColor" format="reference|color" />

<!-- Image Editor -->
<attr name="shakyImageEditorBackgroundColor" format="reference|color" />
Expand Down
Loading