Add a category dropdown in the help fragment.
This commit is contained in:
parent
e7c5eb93dd
commit
07201203b2
5 changed files with 121 additions and 39 deletions
|
@ -6,8 +6,11 @@ import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.Spinner;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.annotation.IdRes;
|
import androidx.annotation.IdRes;
|
||||||
|
@ -32,14 +35,16 @@ import java.util.List;
|
||||||
|
|
||||||
public class HelpFragment extends LoggingFragment {
|
public class HelpFragment extends LoggingFragment {
|
||||||
|
|
||||||
private EditText problem;
|
private EditText problem;
|
||||||
private CheckBox includeDebugLogs;
|
private CheckBox includeDebugLogs;
|
||||||
private View debugLogInfo;
|
private View debugLogInfo;
|
||||||
private View faq;
|
private View faq;
|
||||||
private CircularProgressButton next;
|
private CircularProgressButton next;
|
||||||
private View toaster;
|
private View toaster;
|
||||||
private List<EmojiImageView> emoji;
|
private List<EmojiImageView> emoji;
|
||||||
private HelpViewModel helpViewModel;
|
private HelpViewModel helpViewModel;
|
||||||
|
private Spinner categorySpinner;
|
||||||
|
private ArrayAdapter<CharSequence> categoryAdapter;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
@ -57,7 +62,7 @@ public class HelpFragment extends LoggingFragment {
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__help);
|
((ApplicationPreferencesActivity) requireActivity()).requireSupportActionBar().setTitle(R.string.preferences__help);
|
||||||
|
|
||||||
cancelSpinning(next);
|
cancelSpinning(next);
|
||||||
problem.setEnabled(true);
|
problem.setEnabled(true);
|
||||||
|
@ -74,6 +79,7 @@ public class HelpFragment extends LoggingFragment {
|
||||||
faq = view.findViewById(R.id.help_fragment_faq);
|
faq = view.findViewById(R.id.help_fragment_faq);
|
||||||
next = view.findViewById(R.id.help_fragment_next);
|
next = view.findViewById(R.id.help_fragment_next);
|
||||||
toaster = view.findViewById(R.id.help_fragment_next_toaster);
|
toaster = view.findViewById(R.id.help_fragment_next_toaster);
|
||||||
|
categorySpinner = view.findViewById(R.id.help_fragment_category);
|
||||||
emoji = new ArrayList<>(Feeling.values().length);
|
emoji = new ArrayList<>(Feeling.values().length);
|
||||||
|
|
||||||
for (Feeling feeling : Feeling.values()) {
|
for (Feeling feeling : Feeling.values()) {
|
||||||
|
@ -81,6 +87,11 @@ public class HelpFragment extends LoggingFragment {
|
||||||
emojiView.setImageEmoji(feeling.getEmojiCode());
|
emojiView.setImageEmoji(feeling.getEmojiCode());
|
||||||
emoji.add(view.findViewById(feeling.getViewId()));
|
emoji.add(view.findViewById(feeling.getViewId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
categoryAdapter = ArrayAdapter.createFromResource(requireContext(), R.array.HelpFragment__categories, android.R.layout.simple_spinner_item);
|
||||||
|
categoryAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||||
|
|
||||||
|
categorySpinner.setAdapter(categoryAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeListeners() {
|
private void initializeListeners() {
|
||||||
|
@ -90,6 +101,16 @@ public class HelpFragment extends LoggingFragment {
|
||||||
debugLogInfo.setOnClickListener(v -> launchDebugLogInfo());
|
debugLogInfo.setOnClickListener(v -> launchDebugLogInfo());
|
||||||
next.setOnClickListener(v -> submitForm());
|
next.setOnClickListener(v -> submitForm());
|
||||||
toaster.setOnClickListener(v -> Toast.makeText(requireContext(), R.string.HelpFragment__please_be_as_descriptive_as_possible, Toast.LENGTH_LONG).show());
|
toaster.setOnClickListener(v -> Toast.makeText(requireContext(), R.string.HelpFragment__please_be_as_descriptive_as_possible, Toast.LENGTH_LONG).show());
|
||||||
|
categorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
helpViewModel.onCategorySelected(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> parent) {
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeObservers() {
|
private void initializeObservers() {
|
||||||
|
@ -144,6 +165,7 @@ public class HelpFragment extends LoggingFragment {
|
||||||
.map(view -> Feeling.getByViewId(view.getId()))
|
.map(view -> Feeling.getByViewId(view.getId()))
|
||||||
.findFirst().orElse(null);
|
.findFirst().orElse(null);
|
||||||
|
|
||||||
|
|
||||||
CommunicationActions.openEmail(requireContext(),
|
CommunicationActions.openEmail(requireContext(),
|
||||||
SupportEmailUtil.getSupportEmailAddress(requireContext()),
|
SupportEmailUtil.getSupportEmailAddress(requireContext()),
|
||||||
getEmailSubject(),
|
getEmailSubject(),
|
||||||
|
@ -171,8 +193,11 @@ public class HelpFragment extends LoggingFragment {
|
||||||
suffix.append(getString(feeling.getStringId()));
|
suffix.append(getString(feeling.getStringId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String category = categoryAdapter.getItem(helpViewModel.getCategoryIndex()).toString();
|
||||||
|
|
||||||
return SupportEmailUtil.generateSupportEmailBody(requireContext(),
|
return SupportEmailUtil.generateSupportEmailBody(requireContext(),
|
||||||
R.string.HelpFragment__signal_android_support_request,
|
R.string.HelpFragment__signal_android_support_request,
|
||||||
|
" - " + category,
|
||||||
problem.getText().toString() + "\n\n",
|
problem.getText().toString() + "\n\n",
|
||||||
suffix.toString());
|
suffix.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public class HelpViewModel extends ViewModel {
|
||||||
private MutableLiveData<Boolean> problemMeetsLengthRequirements = new MutableLiveData<>();
|
private MutableLiveData<Boolean> problemMeetsLengthRequirements = new MutableLiveData<>();
|
||||||
private MutableLiveData<Boolean> hasLines = new MutableLiveData<>(false);
|
private MutableLiveData<Boolean> hasLines = new MutableLiveData<>(false);
|
||||||
private LiveData<Boolean> isFormValid = Transformations.map(new LiveDataPair<>(problemMeetsLengthRequirements, hasLines), this::transformValidationData);
|
private LiveData<Boolean> isFormValid = Transformations.map(new LiveDataPair<>(problemMeetsLengthRequirements, hasLines), this::transformValidationData);
|
||||||
|
private int categoryIndex = 0;
|
||||||
|
|
||||||
private final SubmitDebugLogRepository submitDebugLogRepository;
|
private final SubmitDebugLogRepository submitDebugLogRepository;
|
||||||
|
|
||||||
|
@ -43,6 +44,14 @@ public class HelpViewModel extends ViewModel {
|
||||||
problemMeetsLengthRequirements.setValue(problem.length() >= MINIMUM_PROBLEM_CHARS);
|
problemMeetsLengthRequirements.setValue(problem.length() >= MINIMUM_PROBLEM_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void onCategorySelected(int index) {
|
||||||
|
this.categoryIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getCategoryIndex() {
|
||||||
|
return this.categoryIndex;
|
||||||
|
}
|
||||||
|
|
||||||
LiveData<SubmitResult> onSubmitClicked(boolean includeDebugLogs) {
|
LiveData<SubmitResult> onSubmitClicked(boolean includeDebugLogs) {
|
||||||
MutableLiveData<SubmitResult> resultLiveData = new MutableLiveData<>();
|
MutableLiveData<SubmitResult> resultLiveData = new MutableLiveData<>();
|
||||||
|
|
||||||
|
|
|
@ -27,21 +27,35 @@ public final class SupportEmailUtil {
|
||||||
* Generates a support email body with system info near the top.
|
* Generates a support email body with system info near the top.
|
||||||
*/
|
*/
|
||||||
public static @NonNull String generateSupportEmailBody(@NonNull Context context,
|
public static @NonNull String generateSupportEmailBody(@NonNull Context context,
|
||||||
@StringRes int subject,
|
@StringRes int filter,
|
||||||
@Nullable String prefix,
|
@Nullable String prefix,
|
||||||
@Nullable String suffix)
|
@Nullable String suffix)
|
||||||
{
|
{
|
||||||
prefix = Util.firstNonNull(prefix, "");
|
return generateSupportEmailBody(context, filter, null, prefix, suffix);
|
||||||
suffix = Util.firstNonNull(suffix, "");
|
|
||||||
return String.format("%s\n%s\n%s", prefix, buildSystemInfo(context, subject), suffix);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NonNull String buildSystemInfo(@NonNull Context context, @StringRes int subject) {
|
/**
|
||||||
|
* Generates a support email body with system info near the top.
|
||||||
|
*/
|
||||||
|
public static @NonNull String generateSupportEmailBody(@NonNull Context context,
|
||||||
|
@StringRes int filter,
|
||||||
|
@Nullable String filterSuffix,
|
||||||
|
@Nullable String prefix,
|
||||||
|
@Nullable String suffix)
|
||||||
|
{
|
||||||
|
filterSuffix = Util.emptyIfNull(filterSuffix);
|
||||||
|
prefix = Util.emptyIfNull(prefix);
|
||||||
|
suffix = Util.emptyIfNull(suffix);
|
||||||
|
|
||||||
|
return String.format("%s\n%s\n%s", prefix, buildSystemInfo(context, filter, filterSuffix), suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static @NonNull String buildSystemInfo(@NonNull Context context, @StringRes int filter, @NonNull String filterSuffix) {
|
||||||
Resources englishResources = ResourceUtil.getEnglishResources(context);
|
Resources englishResources = ResourceUtil.getEnglishResources(context);
|
||||||
|
|
||||||
return "--- " + context.getString(R.string.HelpFragment__support_info) + " ---" +
|
return "--- " + context.getString(R.string.HelpFragment__support_info) + " ---" +
|
||||||
"\n" +
|
"\n" +
|
||||||
context.getString(R.string.SupportEmailUtil_filter) + " " + englishResources.getString(subject) +
|
context.getString(R.string.SupportEmailUtil_filter) + " " + englishResources.getString(filter) + filterSuffix +
|
||||||
"\n" +
|
"\n" +
|
||||||
context.getString(R.string.SupportEmailUtil_device_info) + " " + getDeviceInfo() +
|
context.getString(R.string.SupportEmailUtil_device_info) + " " + getDeviceInfo() +
|
||||||
"\n" +
|
"\n" +
|
||||||
|
|
|
@ -54,48 +54,43 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/help_fragment_contact" />
|
app:layout_constraintTop_toBottomOf="@id/help_fragment_contact" />
|
||||||
|
|
||||||
<CheckBox
|
<TextView
|
||||||
android:id="@+id/help_fragment_debug"
|
android:id="@+id/help_fragment_category_title"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:checked="true"
|
android:layout_marginTop="16dp"
|
||||||
android:text="@string/HelpFragment__include_debug_log"
|
android:layout_marginEnd="16dp"
|
||||||
|
android:text="@string/HelpFragment__tell_us_why_youre_reaching_out"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:textColor="@color/signal_text_secondary"
|
android:textColor="@color/signal_text_secondary"
|
||||||
android:textSize="14sp"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="@id/help_fragment_debug_info"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@id/help_fragment_debug_info" />
|
app:layout_constraintTop_toBottomOf="@id/help_fragment_problem" />
|
||||||
|
|
||||||
<Button
|
<Spinner
|
||||||
android:id="@+id/help_fragment_debug_info"
|
android:id="@+id/help_fragment_category"
|
||||||
style="@style/Button.Borderless"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="2dp"
|
android:layout_marginTop="8dp"
|
||||||
android:background="@android:color/transparent"
|
android:layout_marginStart="16dp"
|
||||||
android:text="@string/HelpFragment__whats_this"
|
android:layout_marginEnd="16dp"
|
||||||
android:textAllCaps="false"
|
app:layout_constraintTop_toBottomOf="@id/help_fragment_category_title"
|
||||||
android:textAppearance="@style/Signal.Text.Body"
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
android:textSize="14sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0"
|
|
||||||
app:layout_constraintStart_toEndOf="@id/help_fragment_debug"
|
|
||||||
app:layout_constraintTop_toBottomOf="@id/help_fragment_problem" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/help_fragment_feelings"
|
android:id="@+id/help_fragment_feelings"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:text="@string/HelpFragment__how_do_you_feel"
|
android:text="@string/HelpFragment__how_do_you_feel"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:textColor="@color/signal_text_secondary"
|
android:textColor="@color/signal_text_secondary"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@id/help_fragment_debug_info" />
|
app:layout_constraintTop_toBottomOf="@id/help_fragment_category" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
<org.thoughtcrime.securesms.components.emoji.EmojiImageView
|
||||||
android:id="@+id/help_fragment_emoji_5"
|
android:id="@+id/help_fragment_emoji_5"
|
||||||
|
@ -170,6 +165,37 @@
|
||||||
app:layout_constraintStart_toEndOf="@id/help_fragment_emoji_2"
|
app:layout_constraintStart_toEndOf="@id/help_fragment_emoji_2"
|
||||||
app:layout_constraintTop_toTopOf="@id/help_fragment_emoji_2" />
|
app:layout_constraintTop_toTopOf="@id/help_fragment_emoji_2" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/help_fragment_debug"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:checked="true"
|
||||||
|
android:text="@string/HelpFragment__include_debug_log"
|
||||||
|
android:textColor="@color/signal_text_secondary"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/help_fragment_debug_info"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/help_fragment_debug_info" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/help_fragment_debug_info"
|
||||||
|
style="@style/Button.Borderless"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="2dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:text="@string/HelpFragment__whats_this"
|
||||||
|
android:textAllCaps="false"
|
||||||
|
android:textAppearance="@style/Signal.Text.Body"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/help_fragment_debug"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/help_fragment_emoji_1" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
|
@ -2109,6 +2109,7 @@
|
||||||
<string name="HelpFragment__include_debug_log">Include debug log.</string>
|
<string name="HelpFragment__include_debug_log">Include debug log.</string>
|
||||||
<string name="HelpFragment__whats_this">What\'s this?</string>
|
<string name="HelpFragment__whats_this">What\'s this?</string>
|
||||||
<string name="HelpFragment__how_do_you_feel">How do you feel? (Optional)</string>
|
<string name="HelpFragment__how_do_you_feel">How do you feel? (Optional)</string>
|
||||||
|
<string name="HelpFragment__tell_us_why_youre_reaching_out">Tell us why you\'re reaching out.</string>
|
||||||
<string name="HelpFragment__emoji_5" translatable="false">emoji_5</string>
|
<string name="HelpFragment__emoji_5" translatable="false">emoji_5</string>
|
||||||
<string name="HelpFragment__emoji_4" translatable="false">emoji_4</string>
|
<string name="HelpFragment__emoji_4" translatable="false">emoji_4</string>
|
||||||
<string name="HelpFragment__emoji_3" translatable="false">emoji_3</string>
|
<string name="HelpFragment__emoji_3" translatable="false">emoji_3</string>
|
||||||
|
@ -2121,6 +2122,13 @@
|
||||||
<string name="HelpFragment__debug_log">Debug Log:</string>
|
<string name="HelpFragment__debug_log">Debug Log:</string>
|
||||||
<string name="HelpFragment__could_not_upload_logs">Could not upload logs</string>
|
<string name="HelpFragment__could_not_upload_logs">Could not upload logs</string>
|
||||||
<string name="HelpFragment__please_be_as_descriptive_as_possible">Please be as descriptive as possible to help us understand the issue.</string>
|
<string name="HelpFragment__please_be_as_descriptive_as_possible">Please be as descriptive as possible to help us understand the issue.</string>
|
||||||
|
<string-array name="HelpFragment__categories">
|
||||||
|
<item>Something\'s Not Working</item>
|
||||||
|
<item>Feature Request</item>
|
||||||
|
<item>Question</item>
|
||||||
|
<item>Feedback</item>
|
||||||
|
<item>Other</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<!-- ReactWithAnyEmojiBottomSheetDialogFragment -->
|
<!-- ReactWithAnyEmojiBottomSheetDialogFragment -->
|
||||||
<string name="ReactWithAnyEmojiBottomSheetDialogFragment__this_message">This Message</string>
|
<string name="ReactWithAnyEmojiBottomSheetDialogFragment__this_message">This Message</string>
|
||||||
|
|
Loading…
Add table
Reference in a new issue