Skip to content

Commit 66be717

Browse files
authored
Remove progress dialogs (#1280)
2 parents 6b740bc + 4d80006 commit 66be717

25 files changed

+442
-115
lines changed

auth/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ dependencies {
5050
implementation "com.android.support:customtabs:$supportLibraryVersion"
5151
compileOnly("com.twitter.sdk.android:twitter-core:3.1.1@aar") { transitive = true }
5252

53+
// Material progress bar for loading indicators
54+
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
55+
5356
testImplementation 'junit:junit:4.12'
5457
//noinspection GradleDynamicVersion
5558
testImplementation 'org.mockito:mockito-core:2.15.+'

auth/src/main/java/com/firebase/ui/auth/KickoffActivity.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
import com.firebase.ui.auth.data.model.FlowParameters;
1313
import com.firebase.ui.auth.data.model.UserCancellationException;
1414
import com.firebase.ui.auth.data.remote.SignInKickstarter;
15-
import com.firebase.ui.auth.ui.HelperActivityBase;
15+
import com.firebase.ui.auth.ui.InvisibleActivityBase;
1616
import com.firebase.ui.auth.viewmodel.ResourceObserver;
1717
import com.google.android.gms.common.GoogleApiAvailability;
1818
import com.google.android.gms.tasks.OnFailureListener;
1919
import com.google.android.gms.tasks.OnSuccessListener;
2020

2121
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
22-
public class KickoffActivity extends HelperActivityBase {
22+
public class KickoffActivity extends InvisibleActivityBase {
2323
private SignInKickstarter mKickstarter;
2424

2525
public static Intent createIntent(Context context, FlowParameters flowParams) {
@@ -31,8 +31,7 @@ protected void onCreate(@Nullable final Bundle savedInstanceState) {
3131
super.onCreate(savedInstanceState);
3232
mKickstarter = ViewModelProviders.of(this).get(SignInKickstarter.class);
3333
mKickstarter.init(getFlowParams());
34-
mKickstarter.getOperation().observe(this, new ResourceObserver<IdpResponse>(
35-
this, R.string.fui_progress_dialog_loading) {
34+
mKickstarter.getOperation().observe(this, new ResourceObserver<IdpResponse>(this) {
3635
@Override
3736
protected void onSuccess(@NonNull IdpResponse response) {
3837
finish(RESULT_OK, response.toIntent());

auth/src/main/java/com/firebase/ui/auth/ui/FragmentBase.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import com.google.firebase.auth.FirebaseUser;
1212

1313
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
14-
public class FragmentBase extends Fragment {
14+
public class FragmentBase extends Fragment implements ProgressView {
1515
private HelperActivityBase mActivity;
1616
private ProgressDialogHolder mProgressDialogHolder;
1717

@@ -44,4 +44,14 @@ public void startSaveCredentials(
4444
@Nullable String password) {
4545
mActivity.startSaveCredentials(firebaseUser, response, password);
4646
}
47+
48+
@Override
49+
public void showProgress(int message) {
50+
mActivity.showProgress(message);
51+
}
52+
53+
@Override
54+
public void hideProgress() {
55+
mActivity.hideProgress();
56+
}
4757
}

auth/src/main/java/com/firebase/ui/auth/ui/HelperActivityBase.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import android.support.annotation.NonNull;
88
import android.support.annotation.Nullable;
99
import android.support.annotation.RestrictTo;
10+
import android.support.annotation.StringRes;
1011
import android.support.v7.app.AppCompatActivity;
1112

1213
import com.firebase.ui.auth.IdpResponse;
@@ -24,7 +25,7 @@
2425

2526
@SuppressWarnings("Registered")
2627
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
27-
public class HelperActivityBase extends AppCompatActivity {
28+
public class HelperActivityBase extends AppCompatActivity implements ProgressView {
2829
private FlowParameters mParams;
2930

3031
private AuthHelper mAuthHelper;
@@ -74,10 +75,6 @@ public AuthHelper getAuthHelper() {
7475
return mAuthHelper;
7576
}
7677

77-
public ProgressDialogHolder getDialogHolder() {
78-
return mProgressDialogHolder;
79-
}
80-
8178
public void finish(int resultCode, @Nullable Intent intent) {
8279
setResult(resultCode, intent);
8380
finish();
@@ -97,4 +94,18 @@ public void startSaveCredentials(
9794
this, getFlowParams(), credential, response);
9895
startActivityForResult(intent, RequestCodes.CRED_SAVE_FLOW);
9996
}
97+
98+
@Override
99+
public void showProgress(@StringRes int message) {
100+
getDialogHolder().showLoadingDialog(message);
101+
}
102+
103+
@Override
104+
public void hideProgress() {
105+
getDialogHolder().dismissDialog();
106+
}
107+
108+
protected ProgressDialogHolder getDialogHolder() {
109+
return mProgressDialogHolder;
110+
}
100111
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package com.firebase.ui.auth.ui;
2+
3+
import android.content.Intent;
4+
import android.os.Bundle;
5+
import android.os.Handler;
6+
import android.support.annotation.Nullable;
7+
import android.support.annotation.RestrictTo;
8+
import android.view.ContextThemeWrapper;
9+
import android.view.Gravity;
10+
import android.view.View;
11+
import android.view.ViewGroup;
12+
import android.widget.FrameLayout;
13+
14+
import com.firebase.ui.auth.R;
15+
16+
import me.zhanghai.android.materialprogressbar.MaterialProgressBar;
17+
18+
/**
19+
* Base classes for activities that are just simple overlays.
20+
*/
21+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
22+
public class InvisibleActivityBase extends HelperActivityBase {
23+
24+
// Minimum time that the spinner will stay on screen, once it is shown.
25+
private static final long MIN_SPINNER_MS = 750;
26+
27+
private Handler mHandler = new Handler();
28+
private MaterialProgressBar mProgressBar;
29+
30+
// Last time that the progress bar was actually shown
31+
private long mLastShownTime = 0;
32+
33+
@Override
34+
protected void onCreate(@Nullable Bundle savedInstanceState) {
35+
super.onCreate(savedInstanceState);
36+
setContentView(R.layout.fui_activity_invisible);
37+
38+
// Create an indeterminate, circular progress bar in the app's theme
39+
mProgressBar = new MaterialProgressBar(new ContextThemeWrapper(this, getFlowParams().themeId));
40+
mProgressBar.setIndeterminate(true);
41+
mProgressBar.setVisibility(View.GONE);
42+
43+
// Set bar to float in the center
44+
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
45+
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
46+
params.gravity = Gravity.CENTER;
47+
48+
// Add to the container
49+
FrameLayout container = findViewById(R.id.invisible_frame);
50+
container.addView(mProgressBar, params);
51+
}
52+
53+
@Override
54+
public void showProgress(int message) {
55+
if (mProgressBar.getVisibility() == View.VISIBLE) {
56+
mHandler.removeCallbacksAndMessages(null);
57+
return;
58+
}
59+
60+
mLastShownTime = System.currentTimeMillis();
61+
mProgressBar.setVisibility(View.VISIBLE);
62+
}
63+
64+
@Override
65+
public void hideProgress() {
66+
doAfterTimeout(new Runnable() {
67+
@Override
68+
public void run() {
69+
mLastShownTime = 0;
70+
mProgressBar.setVisibility(View.GONE);
71+
}
72+
});
73+
}
74+
75+
@Override
76+
public void finish(int resultCode, @Nullable Intent intent) {
77+
setResult(resultCode, intent);
78+
doAfterTimeout(new Runnable() {
79+
@Override
80+
public void run() {
81+
finish();
82+
}
83+
});
84+
}
85+
86+
/**
87+
* For certain actions (like finishing or hiding the progress dialog) we want to make sure
88+
* that we have shown the progress state for at least MIN_SPINNER_MS to prevent flickering.
89+
*
90+
* This method performs some action after the window has passed, or immediately if we have
91+
* already waited longer than that.
92+
*/
93+
private void doAfterTimeout(Runnable runnable) {
94+
long currentTime = System.currentTimeMillis();
95+
long diff = currentTime - mLastShownTime;
96+
97+
// 'diff' is how long it's been since we showed the spinner, so in the
98+
// case where diff is greater than our minimum spinner duration then our
99+
// remaining wait time is 0.
100+
long remaining = Math.max(MIN_SPINNER_MS - diff, 0);
101+
102+
mHandler.postDelayed(runnable, remaining);
103+
}
104+
}

auth/src/main/java/com/firebase/ui/auth/ui/ProgressDialogHolder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ public ProgressDialogHolder(Context context) {
1818

1919
private void showLoadingDialog(String message) {
2020
dismissDialog();
21-
2221
if (mProgressDialog == null) {
2322
mProgressDialog = new ProgressDialog(mContext);
2423
mProgressDialog.setIndeterminate(true);
@@ -34,10 +33,11 @@ public void showLoadingDialog(@StringRes int stringResource) {
3433
}
3534

3635
public void dismissDialog() {
37-
if (mProgressDialog != null) {
36+
if (isProgressDialogShowing()) {
3837
mProgressDialog.dismiss();
39-
mProgressDialog = null;
4038
}
39+
40+
mProgressDialog = null;
4141
}
4242

4343
public boolean isProgressDialogShowing() {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.firebase.ui.auth.ui;
2+
3+
import android.support.annotation.RestrictTo;
4+
import android.support.annotation.StringRes;
5+
6+
/**
7+
* View (Activity or Fragment, normally) that can respond to progress events.
8+
*/
9+
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
10+
public interface ProgressView {
11+
12+
void showProgress(@StringRes int message);
13+
14+
void hideProgress();
15+
16+
}

auth/src/main/java/com/firebase/ui/auth/ui/credentials/CredentialSaveActivity.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
import android.util.Log;
1010

1111
import com.firebase.ui.auth.IdpResponse;
12-
import com.firebase.ui.auth.R;
1312
import com.firebase.ui.auth.data.model.FlowParameters;
1413
import com.firebase.ui.auth.data.model.Resource;
15-
import com.firebase.ui.auth.ui.HelperActivityBase;
14+
import com.firebase.ui.auth.ui.InvisibleActivityBase;
1615
import com.firebase.ui.auth.util.ExtraConstants;
1716
import com.firebase.ui.auth.viewmodel.ResourceObserver;
1817
import com.firebase.ui.auth.viewmodel.smartlock.SmartLockHandler;
@@ -21,7 +20,7 @@
2120
/**
2221
* Invisible Activity used for saving credentials to SmartLock.
2322
*/
24-
public class CredentialSaveActivity extends HelperActivityBase {
23+
public class CredentialSaveActivity extends InvisibleActivityBase {
2524
private static final String TAG = "CredentialSaveActivity";
2625

2726
private SmartLockHandler mHandler;
@@ -47,8 +46,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
4746
mHandler.init(getFlowParams());
4847
mHandler.setResponse(response);
4948

50-
mHandler.getOperation().observe(this, new ResourceObserver<IdpResponse>(
51-
this, R.string.fui_progress_dialog_loading) {
49+
mHandler.getOperation().observe(this, new ResourceObserver<IdpResponse>(this) {
5250
@Override
5351
protected void onSuccess(@NonNull IdpResponse response) {
5452
finish(RESULT_OK, response.toIntent());

auth/src/main/java/com/firebase/ui/auth/ui/email/CheckEmailFragment.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
import android.view.LayoutInflater;
1313
import android.view.View;
1414
import android.view.ViewGroup;
15+
import android.widget.Button;
1516
import android.widget.EditText;
17+
import android.widget.ProgressBar;
1618
import android.widget.TextView;
1719

1820
import com.firebase.ui.auth.R;
@@ -62,6 +64,9 @@ interface CheckEmailListener {
6264

6365
private CheckEmailHandler mHandler;
6466

67+
private Button mNextButton;
68+
private ProgressBar mProgressBar;
69+
6570
private EditText mEmailEditText;
6671
private TextInputLayout mEmailLayout;
6772

@@ -85,6 +90,9 @@ public View onCreateView(@NonNull LayoutInflater inflater,
8590

8691
@Override
8792
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
93+
mNextButton = view.findViewById(R.id.button_next);
94+
mProgressBar = view.findViewById(R.id.top_progress_bar);
95+
8896
// Email field and validator
8997
mEmailLayout = view.findViewById(R.id.email_layout);
9098
mEmailEditText = view.findViewById(R.id.email);
@@ -98,7 +106,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
98106
mEmailEditText.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
99107
}
100108

101-
view.findViewById(R.id.button_next).setOnClickListener(this);
109+
mNextButton.setOnClickListener(this);
102110

103111
TextView termsText = view.findViewById(R.id.email_tos_and_pp_text);
104112
TextView footerText = view.findViewById(R.id.email_footer_tos_and_pp_text);
@@ -193,4 +201,16 @@ private void validateAndProceed() {
193201
mHandler.fetchProvider(email);
194202
}
195203
}
204+
205+
@Override
206+
public void showProgress(int message) {
207+
mNextButton.setEnabled(false);
208+
mProgressBar.setVisibility(View.VISIBLE);
209+
}
210+
211+
@Override
212+
public void hideProgress() {
213+
mNextButton.setEnabled(true);
214+
mProgressBar.setVisibility(View.INVISIBLE);
215+
}
196216
}

auth/src/main/java/com/firebase/ui/auth/ui/email/RegisterEmailFragment.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
import android.view.LayoutInflater;
1212
import android.view.View;
1313
import android.view.ViewGroup;
14+
import android.widget.Button;
1415
import android.widget.EditText;
16+
import android.widget.ProgressBar;
1517
import android.widget.TextView;
1618

1719
import com.firebase.ui.auth.AuthUI;
@@ -44,6 +46,9 @@ public class RegisterEmailFragment extends FragmentBase implements
4446

4547
private EmailProviderResponseHandler mHandler;
4648

49+
private Button mNextButton;
50+
private ProgressBar mProgressBar;
51+
4752
private EditText mEmailEditText;
4853
private EditText mNameEditText;
4954
private EditText mPasswordEditText;
@@ -112,6 +117,9 @@ public View onCreateView(@NonNull LayoutInflater inflater,
112117

113118
@Override
114119
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
120+
mNextButton = view.findViewById(R.id.button_create);
121+
mProgressBar = view.findViewById(R.id.top_progress_bar);
122+
115123
mEmailEditText = view.findViewById(R.id.email);
116124
mNameEditText = view.findViewById(R.id.name);
117125
mPasswordEditText = view.findViewById(R.id.password);
@@ -137,7 +145,7 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
137145
mEmailEditText.setOnFocusChangeListener(this);
138146
mNameEditText.setOnFocusChangeListener(this);
139147
mPasswordEditText.setOnFocusChangeListener(this);
140-
view.findViewById(R.id.button_create).setOnClickListener(this);
148+
mNextButton.setOnClickListener(this);
141149

142150
// Only show the name field if required
143151
nameInput.setVisibility(requireName ? View.VISIBLE : View.GONE);
@@ -226,6 +234,18 @@ public void onDonePressed() {
226234
validateAndRegisterUser();
227235
}
228236

237+
@Override
238+
public void showProgress(int message) {
239+
mNextButton.setEnabled(false);
240+
mProgressBar.setVisibility(View.VISIBLE);
241+
}
242+
243+
@Override
244+
public void hideProgress() {
245+
mNextButton.setEnabled(true);
246+
mProgressBar.setVisibility(View.INVISIBLE);
247+
}
248+
229249
private void validateAndRegisterUser() {
230250
String email = mEmailEditText.getText().toString();
231251
String password = mPasswordEditText.getText().toString();

0 commit comments

Comments
 (0)