Skip to content

Commit 77c5cdc

Browse files
Merge pull request #267 from MihaiCristianCondrea/codex/update-help-page-design-and-email-intent
Revamp help contact section with support card
2 parents ac30a5f + fb8a46f commit 77c5cdc

File tree

35 files changed

+288
-83
lines changed

35 files changed

+288
-83
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ android {
1313
applicationId 'com.d4rk.androidtutorials.java'
1414
minSdk 23
1515
targetSdk 36
16-
versionCode 50
16+
versionCode 51
1717
versionName '5.0.2'
1818
vectorDrawables.useSupportLibrary = true
1919
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'

app/src/main/java/com/d4rk/androidtutorials/java/ui/screens/help/HelpActivity.java

Lines changed: 65 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,18 @@
44
import android.content.Intent;
55
import android.net.Uri;
66
import android.os.Bundle;
7+
import android.os.Handler;
8+
import android.os.Looper;
79
import android.view.LayoutInflater;
810
import android.view.Menu;
911
import android.view.MenuItem;
1012
import android.view.View;
11-
import android.view.ViewGroup;
12-
import android.widget.FrameLayout;
13-
14-
import androidx.annotation.Nullable;
1513
import androidx.annotation.NonNull;
1614
import androidx.annotation.StringRes;
1715
import androidx.appcompat.app.AlertDialog;
1816
import androidx.appcompat.widget.LinearLayoutCompat;
1917
import androidx.core.view.ViewCompat;
2018
import androidx.lifecycle.ViewModelProvider;
21-
import androidx.preference.Preference;
22-
import androidx.preference.PreferenceFragmentCompat;
23-
import androidx.recyclerview.widget.RecyclerView;
2419

2520
import com.d4rk.androidtutorials.java.BuildConfig;
2621
import com.d4rk.androidtutorials.java.R;
@@ -43,7 +38,9 @@
4338
@AndroidEntryPoint
4439
public class HelpActivity extends BaseActivity {
4540

41+
private ActivityHelpBinding binding;
4642
private HelpViewModel helpViewModel;
43+
private final Handler handler = new Handler(Looper.getMainLooper());
4744
private static final List<FaqItem> FAQ_ITEMS = Arrays.asList(
4845
new FaqItem(R.string.question_1, R.string.summary_preference_faq_1),
4946
new FaqItem(R.string.question_2, R.string.summary_preference_faq_2),
@@ -59,22 +56,17 @@ public class HelpActivity extends BaseActivity {
5956
@Override
6057
protected void onCreate(Bundle savedInstanceState) {
6158
super.onCreate(savedInstanceState);
62-
ActivityHelpBinding binding = ActivityHelpBinding.inflate(getLayoutInflater());
59+
binding = ActivityHelpBinding.inflate(getLayoutInflater());
6360
setContentView(binding.getRoot());
6461
AdUtils.loadBanner(binding.faqNativeAd);
6562
helpViewModel = new ViewModelProvider(this).get(HelpViewModel.class);
6663
new FastScrollerBuilder(binding.scrollView)
6764
.useMd2Style()
6865
.build();
6966
bindFaqItems(binding);
70-
71-
getSupportFragmentManager().beginTransaction()
72-
.replace(R.id.frame_layout_feedback, new FeedbackFragment())
73-
.commit();
74-
}
75-
76-
public HelpViewModel getHelpViewModel() {
77-
return helpViewModel;
67+
setupContactSupportCard();
68+
setupFeedbackFab();
69+
handler.postDelayed(() -> binding.fabContactSupport.shrink(), 5000L);
7870
}
7971

8072
@Override
@@ -141,73 +133,66 @@ private void openLink(String url) {
141133
startActivity(browserIntent);
142134
}
143135

144-
public static class FeedbackFragment extends PreferenceFragmentCompat {
145-
146-
@Override
147-
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
148-
setPreferencesFromResource(R.xml.preferences_feedback, rootKey);
149-
150-
Preference feedbackPreference = findPreference(getString(R.string.key_feedback));
151-
if (feedbackPreference != null) {
152-
feedbackPreference.setOnPreferenceClickListener(preference -> {
153-
if (requireActivity() instanceof HelpActivity helpActivity) {
154-
HelpViewModel vm = helpActivity.getHelpViewModel();
136+
private void setupContactSupportCard() {
137+
binding.contactSupportCard.setOnClickListener(v -> openSupportEmail());
138+
}
155139

156-
vm.requestReviewFlow(new HelpRepository.OnReviewInfoListener() {
157-
@Override
158-
public void onSuccess(ReviewInfo info) {
159-
vm.launchReviewFlow(helpActivity, info);
160-
}
140+
private void setupFeedbackFab() {
141+
binding.fabContactSupport.setOnClickListener(v -> requestReview());
142+
binding.fabContactSupport.setContentDescription(getString(R.string.send_feedback));
143+
}
161144

162-
@Override
163-
public void onFailure(Exception e) {
164-
launchGooglePlayReviews();
165-
}
166-
});
167-
}
168-
return true;
169-
});
170-
}
145+
private void openSupportEmail() {
146+
String supportEmail = getString(R.string.contact_support_email);
147+
Intent intent = new Intent(Intent.ACTION_SENDTO);
148+
intent.setData(Uri.fromParts("mailto", supportEmail, null));
149+
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{supportEmail});
150+
intent.putExtra(Intent.EXTRA_SUBJECT,
151+
getString(R.string.contact_support_email_subject, getString(R.string.app_name)));
152+
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.contact_support_email_body));
153+
154+
if (intent.resolveActivity(getPackageManager()) != null) {
155+
startActivity(Intent.createChooser(intent, getString(R.string.contact_support_title)));
156+
} else {
157+
Snackbar.make(binding.getRoot(), R.string.support_link_unavailable, Snackbar.LENGTH_SHORT).show();
171158
}
159+
}
172160

173-
@Override
174-
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
175-
super.onViewCreated(view, savedInstanceState);
176-
RecyclerView listView = getListView();
177-
listView.setNestedScrollingEnabled(false);
178-
listView.setOverScrollMode(View.OVER_SCROLL_NEVER);
179-
listView.setClipToPadding(false);
180-
181-
ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
182-
FrameLayout.LayoutParams frameLayoutParams;
183-
if (layoutParams instanceof FrameLayout.LayoutParams) {
184-
frameLayoutParams = (FrameLayout.LayoutParams) layoutParams;
185-
} else {
186-
frameLayoutParams = new FrameLayout.LayoutParams(
187-
ViewGroup.LayoutParams.MATCH_PARENT,
188-
ViewGroup.LayoutParams.WRAP_CONTENT
189-
);
161+
private void requestReview() {
162+
binding.fabContactSupport.setEnabled(false);
163+
helpViewModel.requestReviewFlow(new HelpRepository.OnReviewInfoListener() {
164+
@Override
165+
public void onSuccess(ReviewInfo info) {
166+
helpViewModel.launchReviewFlow(HelpActivity.this, info);
167+
binding.fabContactSupport.setEnabled(true);
190168
}
191-
frameLayoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
192-
frameLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
193-
listView.setLayoutParams(frameLayoutParams);
194-
}
195169

196-
private void launchGooglePlayReviews() {
197-
Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=" + requireActivity().getPackageName() + "&showAllReviews=true");
198-
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
199-
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
200-
try {
201-
startActivity(intent);
202-
} catch (ActivityNotFoundException e) {
203-
Snackbar.make(requireView(),
204-
R.string.snack_unable_to_open_google_play_store,
205-
Snackbar.LENGTH_SHORT)
206-
.show();
170+
@Override
171+
public void onFailure(Exception e) {
172+
binding.fabContactSupport.setEnabled(true);
173+
launchGooglePlayReviews();
207174
}
175+
});
176+
}
177+
178+
private void launchGooglePlayReviews() {
179+
Uri uri = Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName() + "&showAllReviews=true");
180+
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
181+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
182+
try {
183+
startActivity(intent);
184+
} catch (ActivityNotFoundException e) {
185+
Snackbar.make(binding.getRoot(),
186+
R.string.snack_unable_to_open_google_play_store,
187+
Snackbar.LENGTH_SHORT)
188+
.show();
208189
}
209190
}
210191

192+
public HelpViewModel getHelpViewModel() {
193+
return helpViewModel;
194+
}
195+
211196
private void bindFaqItems(ActivityHelpBinding binding) {
212197
LinearLayoutCompat faqList = binding.faqList;
213198
faqList.removeAllViews();
@@ -261,4 +246,10 @@ private FaqItem(@StringRes int questionResId, @StringRes int answerResId) {
261246
this.answerResId = answerResId;
262247
}
263248
}
264-
}
249+
250+
@Override
251+
protected void onDestroy() {
252+
handler.removeCallbacksAndMessages(null);
253+
super.onDestroy();
254+
}
255+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="289dp"
4+
android:height="289dp"
5+
android:viewportWidth="289"
6+
android:viewportHeight="289">
7+
8+
<path
9+
android:fillColor="?attr/colorSecondaryContainer"
10+
android:pathData="M3.2,160.9c-3.9-6.6-4.2-14.7-0.8-21.6l4.8-9.7c2-4.1,2.8-8.8,2.1-13.3l-1.6-10.7C6.6,98,9.4,90.4,15.2,85.3 l8.1-7.1c3.4-3,5.9-7,7-11.5L33,56.2c1.9-7.5,7.4-13.4,14.7-15.9l10.2-3.5c4.4-1.5,8.2-4.2,10.9-7.9l6.4-8.7 c4.6-6.2,12-9.6,19.7-9.1l10.8,0.7c4.6,0.3,9.2-0.8,13.1-3.1l9.3-5.5c6.6-3.9,14.7-4.3,21.6-0.8l9.7,4.8c4.1,2,8.8,2.8,13.3,2.1 l10.7-1.6c7.6-1.1,15.2,1.7,20.3,7.5l7.1,8.1c3,3.4,7,5.9,11.5,7l10.5,2.7c7.5,1.9,13.4,7.4,15.9,14.7l3.5,10.2 c1.5,4.4,4.2,8.2,7.9,10.9l8.7,6.4c6.2,4.6,9.6,12,9.1,19.7l-0.7,10.8c-0.3,4.6,0.8,9.2,3.1,13.1l5.5,9.3c3.9,6.6,4.2,14.7,0.8,21.6 l-4.8,9.7c-2,4.1-2.8,8.8-2.1,13.3l1.6,10.7c1.1,7.6-1.7,15.2-7.5,20.3l-8.1,7.1c-3.4,3-5.9,7-7,11.5l-2.7,10.5 c-1.9,7.5-7.4,13.4-14.7,15.9l-10.2,3.5c-4.4,1.5-8.2,4.2-10.9,7.9l-6.4,8.7c-4.6,6.2-12,9.6-19.7,9.1l-10.8-0.7 c-4.6-0.3-9.2,0.8-13.1,3.1l-9.3,5.5c-6.6,3.9-14.7,4.3-21.6,0.8l-9.7-4.8c-4.1-2-8.8-2.8-13.3-2.1l-10.7,1.6 c-7.6,1.1-15.2-1.7-20.3-7.5l-7.1-8.1c-3-3.4-7-5.9-11.5-7L56.2,256c-7.5-1.9-13.4-7.4-15.9-14.7l-3.5-10.2 c-1.5-4.4-4.2-8.2-7.9-10.9l-8.7-6.4c-6.2-4.6-9.6-12-9.1-19.7l0.7-10.8c0.3-4.6-0.8-9.2-3.1-13.1L3.2,160.9L3.2,160.9z" />
11+
</vector>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
8+
<path
9+
android:fillColor="#000000"
10+
android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M19.46,9.12l-2.78,1.15 c-0.51-1.36-1.58-2.44-2.95-2.94l1.15-2.78C16.98,5.35,18.65,7.02,19.46,9.12z M12,15c-1.66,0-3-1.34-3-3s1.34-3,3-3s3,1.34,3,3 S13.66,15,12,15z M9.13,4.54l1.17,2.78c-1.38,0.5-2.47,1.59-2.98,2.97L4.54,9.13C5.35,7.02,7.02,5.35,9.13,4.54z M4.54,14.87 l2.78-1.15c0.51,1.38,1.59,2.46,2.97,2.96l-1.17,2.78C7.02,18.65,5.35,16.98,4.54,14.87z M14.88,19.46l-1.15-2.78 c1.37-0.51,2.45-1.59,2.95-2.97l2.78,1.17C18.65,16.98,16.98,18.65,14.88,19.46z" />
11+
</vector>

app/src/main/res/layout/activity_help.xml

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<androidx.constraintlayout.widget.ConstraintLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android"
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
43
xmlns:app="http://schemas.android.com/apk/res-auto"
54
android:id="@+id/container"
65
android:layout_width="match_parent"
@@ -37,7 +36,6 @@
3736
style="@style/Widget.Material3.CardView.Filled"
3837
android:layout_width="match_parent"
3938
android:layout_height="wrap_content"
40-
android:layout_marginBottom="2dp"
4139
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.CardViewTopRoundedFilled">
4240

4341
<androidx.appcompat.widget.LinearLayoutCompat
@@ -51,16 +49,85 @@
5149
android:id="@+id/faq_native_ad"
5250
android:layout_width="match_parent"
5351
android:layout_height="wrap_content"
54-
android:layout_marginBottom="24dp"
52+
android:layout_marginVertical="2dp"
5553
app:nativeAdLayout="@layout/ad_help" />
5654

57-
<FrameLayout
58-
android:id="@+id/frame_layout_feedback"
55+
<com.google.android.material.card.MaterialCardView
56+
android:id="@+id/contact_support_card"
57+
style="@style/Widget.Material3.CardView.Filled"
5958
android:layout_width="match_parent"
60-
android:layout_height="wrap_content" />
59+
android:layout_height="wrap_content"
60+
android:clickable="true"
61+
android:focusable="true"
62+
android:foreground="?attr/selectableItemBackground"
63+
app:cardBackgroundColor="?attr/colorSurfaceVariant"
64+
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.CardViewBottomRoundedFilled">
65+
66+
<androidx.appcompat.widget.LinearLayoutCompat
67+
android:layout_width="match_parent"
68+
android:layout_height="wrap_content"
69+
android:gravity="center_vertical"
70+
android:orientation="horizontal"
71+
android:paddingStart="20dp"
72+
android:paddingTop="20dp"
73+
android:paddingEnd="20dp"
74+
android:paddingBottom="20dp">
75+
76+
<FrameLayout
77+
android:layout_width="48dp"
78+
android:layout_height="48dp"
79+
android:background="@drawable/bg_contact_support_icon"
80+
android:padding="12dp">
81+
82+
<androidx.appcompat.widget.AppCompatImageView
83+
android:layout_width="match_parent"
84+
android:layout_height="match_parent"
85+
android:contentDescription="@null"
86+
android:src="@drawable/ic_contact_support"
87+
android:tint="?attr/colorOnSecondaryContainer" />
88+
89+
</FrameLayout>
90+
91+
<androidx.appcompat.widget.LinearLayoutCompat
92+
android:layout_width="0dp"
93+
android:layout_height="wrap_content"
94+
android:layout_marginStart="16dp"
95+
android:layout_weight="1"
96+
android:orientation="vertical">
97+
98+
<com.google.android.material.textview.MaterialTextView
99+
android:id="@+id/contact_support_title"
100+
android:layout_width="wrap_content"
101+
android:layout_height="wrap_content"
102+
android:text="@string/contact_support_title"
103+
android:textAppearance="@style/TextAppearance.Material3.TitleMedium" />
104+
105+
<com.google.android.material.textview.MaterialTextView
106+
android:id="@+id/contact_support_description"
107+
android:layout_width="wrap_content"
108+
android:layout_height="wrap_content"
109+
android:layout_marginTop="4dp"
110+
android:text="@string/contact_support_description"
111+
android:textAppearance="@style/TextAppearance.Material3.BodyMedium" />
112+
113+
</androidx.appcompat.widget.LinearLayoutCompat>
114+
115+
</androidx.appcompat.widget.LinearLayoutCompat>
116+
117+
</com.google.android.material.card.MaterialCardView>
61118

62119
</androidx.appcompat.widget.LinearLayoutCompat>
63120

64121
</me.zhanghai.android.fastscroll.FastScrollScrollView>
65122

123+
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
124+
android:id="@+id/fab_contact_support"
125+
android:layout_width="wrap_content"
126+
android:layout_height="wrap_content"
127+
android:layout_margin="16dp"
128+
android:text="@string/send_feedback"
129+
app:icon="@drawable/ic_rate_review"
130+
app:layout_constraintBottom_toBottomOf="parent"
131+
app:layout_constraintEnd_toEndOf="parent" />
132+
66133
</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/layout/ad_help.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
android:layout_height="wrap_content">
66

77
<com.google.android.material.card.MaterialCardView
8+
android:id="@+id/ad_card"
89
style="@style/Widget.Material3.CardView.Filled"
910
android:layout_width="match_parent"
1011
android:layout_height="wrap_content"
11-
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.CardViewBottomRoundedFilled">
12+
app:cardCornerRadius="4dp">
1213

1314
<androidx.appcompat.widget.LinearLayoutCompat
1415
android:layout_width="match_parent"

app/src/main/res/layout/item_help_faq.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@
3838
android:paddingVertical="12dp"
3939
tools:targetApi="31">
4040

41+
<com.google.android.material.imageview.ShapeableImageView
42+
android:id="@+id/question_icon"
43+
android:layout_width="36dp"
44+
android:layout_height="36dp"
45+
android:layout_marginHorizontal="4dp"
46+
app:contentPadding="6dp"
47+
android:src="@drawable/ic_feedback"
48+
android:background="?attr/colorPrimaryContainer"
49+
app:shapeAppearanceOverlay="@style/ShapeAppearance.Material3.Corner.Full"
50+
app:tint="?attr/colorOnSurfaceVariant" />
51+
4152
<com.google.android.material.textview.MaterialTextView
4253
android:id="@+id/question"
4354
android:layout_width="0dp"

app/src/main/res/values-ar-rEG/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@
290290
<string name="help">مساعدة</string>
291291
<string name="faq">الأسئلة الشائعة</string>
292292
<string name="send_feedback">إرسال رأيك</string>
293+
<string name="contact_support_title">التواصل مع الدعم</string>
294+
<string name="contact_support_description">شارك التفاصيل للحصول على المساعدة في تحقيق هدفك</string>
295+
<string name="contact_support_email_subject">طلب دعم لـ %1$s</string>
296+
<string name="contact_support_email_body">مرحبًا بالفريق،\n\nيُرجى وصف هدفك وأي مشكلات تواجهها حتى نتمكن من مساعدتك.</string>
293297
<string name="license">الترخيص</string>
294298
<string name="share">مشاركة</string>
295299
<string name="share_subject">جربه الآن.</string>

app/src/main/res/values-bg-rBG/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@
316316
<string name="help">Помощ</string>
317317
<string name="faq">Често задавани въпроси</string>
318318
<string name="send_feedback">Изпращане на обратна връзка</string>
319+
<string name="contact_support_title">Свържете се с поддръжката</string>
320+
<string name="contact_support_description">Споделете подробности, за да получите помощ за постигане на целта си</string>
321+
<string name="contact_support_email_subject">Заявка за поддръжка за %1$s</string>
322+
<string name="contact_support_email_body">Здравейте, екип,\n\nМоля, опишете своята цел и всички проблеми, с които се сблъсквате, за да можем да помогнем.</string>
319323
<string name="license">Лиценз</string>
320324
<string name="share">Споделяне</string>
321325
<string name="share_subject">Опитайте сега.</string>

0 commit comments

Comments
 (0)