Skip to content

Commit f4b135d

Browse files
authored
Merge pull request #1277 from woocommerce/merge/WordPress-Login-Flow-Android/24
Merge recent WordPress-Login-Flow-Android changes
2 parents 99ace94 + adbc5ca commit f4b135d

15 files changed

+244
-63
lines changed

libs/login/build.gradle

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ android {
2121
buildToolsVersion "28.0.3"
2222

2323
defaultConfig {
24-
minSdkVersion 16
25-
targetSdkVersion 26
24+
minSdkVersion 17
25+
targetSdkVersion 28
2626
versionCode 2
2727
versionName "1.1"
2828

@@ -68,6 +68,12 @@ dependencies {
6868
annotationProcessor 'com.google.dagger:dagger-android-processor:2.22.1'
6969

7070
lintChecks 'org.wordpress:lint:1.0.1'
71+
72+
testImplementation 'junit:junit:4.12'
73+
testImplementation 'org.mockito:mockito-core:2.27.0'
74+
testImplementation 'androidx.arch.core:core-testing:2.0.1'
75+
testImplementation 'org.robolectric:robolectric:3.6.1'
76+
testImplementation 'org.assertj:assertj-core:3.11.1'
7177
}
7278

7379
// Add properties named "wp.xxx" to our BuildConfig

libs/login/src/main/java/org/wordpress/android/login/LoginSiteAddressFragment.java

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import android.content.Intent;
66
import android.os.Bundle;
77
import android.text.Editable;
8-
import android.text.TextUtils;
98
import android.text.TextWatcher;
10-
import android.util.Patterns;
119
import android.view.View;
1210
import android.view.View.OnClickListener;
1311
import android.view.ViewGroup;
@@ -18,6 +16,7 @@
1816
import androidx.annotation.LayoutRes;
1917
import androidx.annotation.NonNull;
2018
import androidx.annotation.Nullable;
19+
import androidx.lifecycle.Observer;
2120

2221
import org.greenrobot.eventbus.Subscribe;
2322
import org.greenrobot.eventbus.ThreadMode;
@@ -57,6 +56,8 @@ public class LoginSiteAddressFragment extends LoginBaseFormFragment<LoginListene
5756

5857
private String mRequestedSiteAddress;
5958

59+
private LoginSiteAddressValidator mLoginSiteAddressValidator;
60+
6061
@Inject AccountStore mAccountStore;
6162
@Inject Dispatcher mDispatcher;
6263
@Inject HTTPAuthManager mHTTPAuthManager;
@@ -139,6 +140,23 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
139140
} else {
140141
mAnalyticsListener.trackUrlFormViewed();
141142
}
143+
144+
mLoginSiteAddressValidator = new LoginSiteAddressValidator();
145+
146+
mLoginSiteAddressValidator.getIsValid().observe(this, new Observer<Boolean>() {
147+
@Override public void onChanged(Boolean enabled) {
148+
getPrimaryButton().setEnabled(enabled);
149+
}
150+
});
151+
mLoginSiteAddressValidator.getErrorMessageResId().observe(this, new Observer<Integer>() {
152+
@Override public void onChanged(Integer resId) {
153+
if (resId != null) {
154+
showError(resId);
155+
} else {
156+
mSiteAddressInput.setError(null);
157+
}
158+
}
159+
});
142160
}
143161

144162
@Override
@@ -148,24 +166,17 @@ public void onSaveInstanceState(Bundle outState) {
148166
outState.putString(KEY_REQUESTED_SITE_ADDRESS, mRequestedSiteAddress);
149167
}
150168

169+
@Override public void onDestroyView() {
170+
super.onDestroyView();
171+
mLoginSiteAddressValidator.dispose();
172+
}
173+
151174
protected void discover() {
152175
if (!NetworkUtils.checkConnection(getActivity())) {
153176
return;
154177
}
155178

156-
String cleanedSiteAddress = getCleanedSiteAddress();
157-
158-
if (TextUtils.isEmpty(cleanedSiteAddress)) {
159-
showError(R.string.login_empty_site_url);
160-
return;
161-
}
162-
163-
if (!Patterns.WEB_URL.matcher(cleanedSiteAddress).matches()) {
164-
showError(R.string.login_invalid_site_url);
165-
return;
166-
}
167-
168-
mRequestedSiteAddress = cleanedSiteAddress;
179+
mRequestedSiteAddress = mLoginSiteAddressValidator.getCleanedSiteAddress();
169180

170181
String cleanedXmlrpcSuffix = UrlUtils.removeXmlrpcSuffix(mRequestedSiteAddress);
171182

@@ -182,17 +193,16 @@ protected void discover() {
182193
startProgress();
183194
}
184195

185-
private String getCleanedSiteAddress() {
186-
return EditTextUtils.getText(mSiteAddressInput.getEditText()).trim().replaceAll("[\r\n]", "");
187-
}
188-
189196
@Override
190197
public void onEditorCommit() {
191-
discover();
198+
if (getPrimaryButton().isEnabled()) {
199+
discover();
200+
}
192201
}
193202

194203
@Override
195204
public void afterTextChanged(Editable s) {
205+
mLoginSiteAddressValidator.setAddress(EditTextUtils.getText(mSiteAddressInput.getEditText()));
196206
}
197207

198208
@Override
@@ -359,7 +369,7 @@ public void onDiscoverySucceeded(OnDiscoveryResponse event) {
359369
return;
360370
} else {
361371
AppLog.e(T.API, "onDiscoveryResponse has error: " + event.error.name()
362-
+ " - " + event.error.toString());
372+
+ " - " + event.error.toString());
363373
handleDiscoveryError(event.error, event.failedEndpoint);
364374
return;
365375
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.wordpress.android.login;
2+
3+
import android.util.Patterns;
4+
5+
import androidx.annotation.NonNull;
6+
import androidx.lifecycle.LiveData;
7+
import androidx.lifecycle.MutableLiveData;
8+
9+
import org.wordpress.android.util.helpers.Debouncer;
10+
11+
import java.util.concurrent.TimeUnit;
12+
13+
/**
14+
* Encapsulates the site address validation, cleaning, and error reporting of {@link LoginSiteAddressFragment}.
15+
*/
16+
class LoginSiteAddressValidator {
17+
private static final int SECONDS_DELAY_BEFORE_SHOWING_ERROR_MESSAGE = 2;
18+
19+
private MutableLiveData<Boolean> mIsValid = new MutableLiveData<>();
20+
private MutableLiveData<Integer> mErrorMessageResId = new MutableLiveData<>();
21+
22+
private String mCleanedSiteAddress = "";
23+
private final Debouncer mDebouncer;
24+
25+
@NonNull LiveData<Boolean> getIsValid() {
26+
return mIsValid;
27+
}
28+
29+
@NonNull LiveData<Integer> getErrorMessageResId() {
30+
return mErrorMessageResId;
31+
}
32+
33+
@NonNull String getCleanedSiteAddress() {
34+
return mCleanedSiteAddress;
35+
}
36+
37+
LoginSiteAddressValidator() {
38+
this(new Debouncer());
39+
}
40+
41+
LoginSiteAddressValidator(@NonNull Debouncer debouncer) {
42+
mIsValid.setValue(false);
43+
mDebouncer = debouncer;
44+
}
45+
46+
void dispose() {
47+
mDebouncer.shutdown();
48+
}
49+
50+
void setAddress(@NonNull String siteAddress) {
51+
mCleanedSiteAddress = cleanSiteAddress(siteAddress);
52+
final boolean isValid = siteAddressIsValid(mCleanedSiteAddress);
53+
54+
mIsValid.setValue(isValid);
55+
mErrorMessageResId.setValue(null);
56+
57+
// Call debounce regardless if there was an error so that the previous Runnable will be cancelled.
58+
mDebouncer.debounce(Void.class, new Runnable() {
59+
@Override public void run() {
60+
if (!isValid && !mCleanedSiteAddress.isEmpty()) {
61+
mErrorMessageResId.postValue(R.string.login_invalid_site_url);
62+
}
63+
}
64+
}, SECONDS_DELAY_BEFORE_SHOWING_ERROR_MESSAGE, TimeUnit.SECONDS);
65+
}
66+
67+
private static String cleanSiteAddress(@NonNull String siteAddress) {
68+
return siteAddress.trim().replaceAll("[\r\n]", "");
69+
}
70+
71+
private static boolean siteAddressIsValid(@NonNull String cleanedSiteAddress) {
72+
return Patterns.WEB_URL.matcher(cleanedSiteAddress).matches();
73+
}
74+
}

libs/login/src/main/res/layout-land/login_magic_link_request_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@
5050
android:layout_width="match_parent"
5151
android:layout_height="wrap_content"
5252
android:background="@color/login_background_color"
53-
android:paddingLeft="@dimen/margin_small_medium"
5453
android:paddingStart="@dimen/margin_small_medium"
55-
android:paddingRight="@dimen/margin_medium_large"
5654
android:paddingEnd="@dimen/margin_medium_large"
5755
android:paddingTop="@dimen/margin_medium_large"
5856
android:paddingBottom="@dimen/margin_medium_large"
@@ -65,15 +63,12 @@
6563
android:id="@+id/login_enter_password"
6664
android:layout_width="wrap_content"
6765
android:layout_height="wrap_content"
68-
android:layout_alignParentLeft="true"
6966
android:layout_alignParentStart="true"
70-
android:layout_toLeftOf="@+id/login_request_magic_link"
7167
android:layout_toStartOf="@+id/login_request_magic_link"
7268
android:paddingLeft="@dimen/margin_medium_large"
7369
android:paddingStart="@dimen/margin_medium_large"
7470
android:paddingRight="@dimen/margin_medium_large"
7571
android:paddingEnd="@dimen/margin_medium_large"
76-
android:layout_marginRight="@dimen/margin_extra_large"
7772
android:layout_marginEnd="@dimen/margin_extra_large"
7873
android:gravity="start|center_vertical"
7974
android:text="@string/enter_your_password_instead"/>
@@ -83,7 +78,6 @@
8378
android:id="@+id/login_request_magic_link"
8479
android:layout_width="wrap_content"
8580
android:layout_height="wrap_content"
86-
android:layout_alignParentRight="true"
8781
android:layout_alignParentEnd="true"
8882
android:text="@string/send_link" />
8983
</RelativeLayout>

libs/login/src/main/res/layout-land/login_magic_link_sent_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@
3939
android:layout_width="match_parent"
4040
android:layout_height="wrap_content"
4141
android:background="@color/login_background_color"
42-
android:paddingLeft="@dimen/margin_small_medium"
4342
android:paddingStart="@dimen/margin_small_medium"
44-
android:paddingRight="@dimen/margin_medium_large"
4543
android:paddingEnd="@dimen/margin_medium_large"
4644
android:paddingTop="@dimen/margin_medium_large"
4745
android:paddingBottom="@dimen/margin_medium_large"
@@ -54,15 +52,12 @@
5452
android:id="@+id/login_enter_password"
5553
android:layout_width="wrap_content"
5654
android:layout_height="wrap_content"
57-
android:layout_alignParentLeft="true"
5855
android:layout_alignParentStart="true"
59-
android:layout_toLeftOf="@+id/login_open_email_client"
6056
android:layout_toStartOf="@+id/login_open_email_client"
6157
android:paddingLeft="@dimen/margin_medium_large"
6258
android:paddingStart="@dimen/margin_medium_large"
6359
android:paddingRight="@dimen/margin_medium_large"
6460
android:paddingEnd="@dimen/margin_medium_large"
65-
android:layout_marginRight="@dimen/margin_extra_large"
6661
android:layout_marginEnd="@dimen/margin_extra_large"
6762
android:gravity="start|center_vertical"
6863
android:text="@string/enter_your_password_instead"/>
@@ -72,7 +67,6 @@
7267
android:id="@+id/login_open_email_client"
7368
android:layout_width="wrap_content"
7469
android:layout_height="wrap_content"
75-
android:layout_alignParentRight="true"
7670
android:layout_alignParentEnd="true"
7771
android:text="@string/open_mail" />
7872
</RelativeLayout>

libs/login/src/main/res/layout-land/signup_bottom_sheet_dialog.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
android:id="@+id/signup_email"
3535
android:layout_height="match_parent"
3636
android:layout_marginEnd="@dimen/margin_medium"
37-
android:layout_marginRight="@dimen/margin_medium"
3837
android:layout_weight="1"
3938
android:layout_width="wrap_content"
4039
android:text="@string/signup_with_email_button"
@@ -45,7 +44,6 @@
4544
android:id="@+id/signup_google"
4645
android:layout_height="match_parent"
4746
android:layout_marginStart="@dimen/margin_medium"
48-
android:layout_marginLeft="@dimen/margin_medium"
4947
android:layout_weight="1"
5048
android:layout_width="wrap_content"
5149
android:text="@string/signup_with_google_button"

libs/login/src/main/res/layout-land/signup_magic_link.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,13 @@
5353
android:layout_width="match_parent"
5454
android:paddingBottom="@dimen/margin_medium_large"
5555
android:paddingEnd="@dimen/margin_medium_large"
56-
android:paddingLeft="@dimen/margin_small_medium"
57-
android:paddingRight="@dimen/margin_medium_large"
5856
android:paddingStart="@dimen/margin_small_medium"
5957
android:paddingTop="@dimen/margin_medium_large"
6058
tools:ignore="InconsistentLayout">
6159

6260
<androidx.appcompat.widget.AppCompatButton
6361
android:id="@+id/signup_magic_link_button"
6462
android:layout_alignParentEnd="true"
65-
android:layout_alignParentRight="true"
6663
android:layout_height="wrap_content"
6764
android:layout_width="wrap_content"
6865
android:text="@string/open_mail"

libs/login/src/main/res/layout/login_email_password_screen.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
android:layout_width="match_parent"
4242
android:layout_height="wrap_content"
4343
android:orientation="vertical"
44-
android:layout_marginLeft="@dimen/margin_extra_large"
4544
android:layout_marginStart="@dimen/margin_extra_large"
4645
android:focusable="true">
4746

libs/login/src/main/res/layout/login_email_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
android:layout_width="match_parent"
1010
android:orientation="vertical"
1111
android:paddingEnd="@dimen/margin_extra_large"
12-
android:paddingLeft="@dimen/margin_extra_large"
13-
android:paddingRight="@dimen/margin_extra_large"
1412
android:paddingStart="@dimen/margin_extra_large" >
1513

1614
<TextView
@@ -59,7 +57,6 @@
5957
android:orientation="horizontal"
6058
android:paddingBottom="@dimen/margin_medium"
6159
android:paddingEnd="@dimen/margin_medium"
62-
android:paddingRight="@dimen/margin_medium"
6360
android:paddingTop="@dimen/margin_medium"
6461
android:gravity="center_vertical"
6562
tools:ignore="RtlSymmetry" >
@@ -68,7 +65,6 @@
6865
android:importantForAccessibility="no"
6966
android:layout_height="@dimen/google_button_icon_sz"
7067
android:layout_marginEnd="@dimen/margin_medium"
71-
android:layout_marginRight="@dimen/margin_medium"
7268
android:layout_width="@dimen/google_button_icon_sz"
7369
app:srcCompat="@drawable/ic_google_60dp" >
7470
</ImageView>
@@ -94,7 +90,6 @@
9490
android:orientation="horizontal"
9591
android:paddingBottom="@dimen/margin_medium"
9692
android:paddingEnd="@dimen/margin_medium"
97-
android:paddingRight="@dimen/margin_medium"
9893
android:paddingTop="@dimen/margin_medium"
9994
android:gravity="center_vertical"
10095
tools:ignore="RtlSymmetry" >
@@ -104,7 +99,6 @@
10499
android:importantForAccessibility="no"
105100
android:layout_height="@dimen/google_button_icon_sz"
106101
android:layout_marginEnd="@dimen/margin_medium"
107-
android:layout_marginRight="@dimen/margin_medium"
108102
android:layout_width="@dimen/google_button_icon_sz"
109103
app:srcCompat="@drawable/ic_domains_grey_24dp" >
110104
</ImageView>

libs/login/src/main/res/layout/login_form_screen.xml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
android:layout_width="match_parent"
2929
android:layout_height="wrap_content"
3030
android:background="@color/login_background_color"
31-
android:paddingLeft="@dimen/margin_small_medium"
3231
android:paddingStart="@dimen/margin_small_medium"
33-
android:paddingRight="@dimen/margin_medium_large"
3432
android:paddingEnd="@dimen/margin_medium_large"
3533
android:paddingTop="@dimen/margin_medium_large"
3634
android:paddingBottom="@dimen/margin_medium_large"
@@ -42,15 +40,12 @@
4240
android:id="@+id/secondary_button"
4341
android:layout_width="wrap_content"
4442
android:layout_height="wrap_content"
45-
android:layout_alignParentLeft="true"
4643
android:layout_alignParentStart="true"
47-
android:layout_toLeftOf="@+id/primary_button"
4844
android:layout_toStartOf="@+id/primary_button"
4945
android:paddingLeft="@dimen/margin_medium_large"
5046
android:paddingStart="@dimen/margin_medium_large"
5147
android:paddingRight="@dimen/margin_medium_large"
5248
android:paddingEnd="@dimen/margin_medium_large"
53-
android:layout_marginRight="@dimen/margin_extra_large"
5449
android:layout_marginEnd="@dimen/margin_extra_large"
5550
android:textAlignment="viewStart"
5651
android:gravity="start|center_vertical"
@@ -61,7 +56,6 @@
6156
android:id="@+id/primary_button"
6257
android:layout_width="wrap_content"
6358
android:layout_height="wrap_content"
64-
android:layout_alignParentRight="true"
6559
android:layout_alignParentEnd="true"
6660
android:text="@string/next" />
6761
</RelativeLayout>

0 commit comments

Comments
 (0)