Login UX & Pass update on failure

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2017-10-26 20:50:34 +02:00
parent d6086576e6
commit 6a4d0fa73f
9 changed files with 153 additions and 42 deletions

View File

@ -96,6 +96,10 @@ public class AccountVerificationController extends BaseController {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
if (getActionBar() != null) {
getActionBar().hide();
}
dispose(null);
String credentials = ApiHelper.getCredentials(username, token);

View File

@ -110,6 +110,10 @@ public class BottomNavigationController extends BaseController {
protected void onViewBound(@NonNull View view) {
super.onViewBound(view);
if (getActionBar() != null) {
getActionBar().show();
}
/* Setup the BottomNavigationView with the constructor supplied Menu resource */
bottomNavigationView.inflateMenu(getMenuResource());

View File

@ -70,6 +70,7 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@AutoInjector(NextcloudTalkApplication.class)
public class CallsListController extends BaseController implements SearchView.OnQueryTextListener {
@ -230,35 +231,52 @@ public class CallsListController extends BaseController implements SearchView.On
.observeOn(AndroidSchedulers.mainThread())
.subscribe(roomsOverall -> {
if (roomsOverall != null) {
for (int i = 0; i < roomsOverall.getOcs().getData().size(); i++) {
roomItems.add(new RoomItem(roomsOverall.getOcs().getData().get(i), userEntity));
}
adapter.updateDataSet(roomItems, true);
if (searchItem != null) {
searchItem.setVisible(roomItems.size() > 0);
}
cacheQueryDisposable = cacheUtils.createOrUpdateViewCache(
LoganSquare.serialize(roomsOverall.getOcs().getData()),
userEntity.getId(), TAG).subscribe(cacheEntity -> {
// do nothing
}, throwable -> dispose(cacheQueryDisposable),
() -> dispose(cacheQueryDisposable));
}
}, throwable -> {
if (searchItem != null) {
searchItem.setVisible(false);
}
dispose(roomsQueryDisposable);
if (roomsOverall != null) {
for (int i = 0; i < roomsOverall.getOcs().getData().size(); i++) {
roomItems.add(new RoomItem(roomsOverall.getOcs().getData().get(i), userEntity));
}
, () -> {
dispose(roomsQueryDisposable);
if (swipeRefreshLayout != null) {
swipeRefreshLayout.setRefreshing(false);
}
});
adapter.updateDataSet(roomItems, true);
if (searchItem != null) {
searchItem.setVisible(roomItems.size() > 0);
}
cacheQueryDisposable = cacheUtils.createOrUpdateViewCache(
LoganSquare.serialize(roomsOverall.getOcs().getData()),
userEntity.getId(), TAG).subscribe(cacheEntity -> {
// do nothing
}, throwable -> dispose(cacheQueryDisposable),
() -> dispose(cacheQueryDisposable));
}
}, throwable -> {
if (searchItem != null) {
searchItem.setVisible(false);
}
if (throwable instanceof HttpException) {
HttpException exception = (HttpException) throwable;
switch (exception.code()) {
case 401:
if (getParentController() != null &&
getParentController().getRouter() != null) {
getParentController().getRouter().setRoot((RouterTransaction.with
(new WebViewLoginController(userEntity.getBaseUrl(),
true))
.pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler())));
}
break;
default:
break;
}
}
dispose(roomsQueryDisposable);
}, () -> {
dispose(roomsQueryDisposable);
if (swipeRefreshLayout != null) {
swipeRefreshLayout.setRefreshing(false);
}
});
} else {
cacheQueryDisposable = cacheUtils.getViewCache(userEntity.getId(), TAG)
.subscribe(o -> {

View File

@ -75,6 +75,7 @@ import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@AutoInjector(NextcloudTalkApplication.class)
public class ContactsController extends BaseController implements SearchView.OnQueryTextListener {
@ -277,6 +278,25 @@ public class ContactsController extends BaseController implements SearchView.OnQ
if (searchItem != null) {
searchItem.setVisible(false);
}
if (throwable instanceof HttpException) {
HttpException exception = (HttpException) throwable;
switch (exception.code()) {
case 401:
if (getParentController() != null &&
getParentController().getRouter() != null) {
getParentController().getRouter().setRoot((RouterTransaction.with
(new WebViewLoginController(userEntity.getBaseUrl(),
true))
.pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler())));
}
break;
default:
break;
}
}
dispose(contactsQueryDisposable);
}
, () -> {

View File

@ -26,6 +26,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ProgressBar;
import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
@ -54,6 +55,8 @@ public class ServerSelectionController extends BaseController {
ExtendedEditText serverEntry;
@BindView(R.id.text_field_boxes)
TextFieldBoxes textFieldBoxes;
@BindView(R.id.progress_bar)
ProgressBar progressBar;
@Inject
NcApi ncApi;
@ -74,6 +77,10 @@ public class ServerSelectionController extends BaseController {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
if (getActionBar() != null) {
getActionBar().hide();
}
textFieldBoxes.setLabelText(getResources().getString(R.string.nc_app_name) + " " + getResources().getString(R.string.nc_appended_server_url));
serverEntry.requestFocus();
@ -86,6 +93,7 @@ public class ServerSelectionController extends BaseController {
if (url.startsWith("http://") || url.startsWith("https://")) {
serverEntry.setEnabled(false);
progressBar.setVisibility(View.VISIBLE);
if (url.endsWith("/")) {
url = url.substring(0, url.length() - 1);
@ -106,7 +114,7 @@ public class ServerSelectionController extends BaseController {
getResources().getString(R.string.nc_server_product_name))) {
getRouter().pushController(RouterTransaction.with(
new WebViewLoginController(finalServerUrl))
new WebViewLoginController(finalServerUrl, false))
.pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
} else if (!status.isInstalled()) {
@ -133,9 +141,14 @@ public class ServerSelectionController extends BaseController {
if (serverEntry != null) {
serverEntry.setEnabled(true);
}
progressBar.setVisibility(View.GONE);
dispose();
}, this::dispose);
}, () -> {
progressBar.setVisibility(View.GONE);
dispose();
});
} else {
textFieldBoxes.setError(getResources().getString(R.string.nc_server_url_prefix), true);
serverEntry.setEnabled(true);

View File

@ -31,6 +31,7 @@ import android.view.ViewGroup;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import com.bluelinelabs.conductor.RouterTransaction;
import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler;
@ -71,14 +72,19 @@ public class WebViewLoginController extends BaseController {
@BindView(R.id.webview)
WebView webView;
@BindView(R.id.progress_bar)
ProgressBar progressBar;
private String assembledPrefix;
private Disposable userQueryDisposable;
private String baseUrl;
private boolean isPasswordUpdate;
public WebViewLoginController(String baseUrl) {
public WebViewLoginController(String baseUrl, boolean isPasswordUpdate) {
this.baseUrl = baseUrl;
this.isPasswordUpdate = isPasswordUpdate;
}
public WebViewLoginController(Bundle args) {
@ -99,6 +105,10 @@ public class WebViewLoginController extends BaseController {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
if (getActionBar() != null) {
getActionBar().hide();
}
assembledPrefix = getResources().getString(R.string.nc_talk_login_scheme) + PROTOCOL_SUFFIX + "login/";
webView.getSettings().setAllowFileAccess(false);
@ -116,6 +126,7 @@ public class WebViewLoginController extends BaseController {
headers.put("OCS-APIRequest", "true");
webView.setWebViewClient(new WebViewClient() {
private boolean basePageLoaded;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(assembledPrefix)) {
@ -127,8 +138,13 @@ public class WebViewLoginController extends BaseController {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!basePageLoaded) {
progressBar.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
basePageLoaded = true;
}
super.onPageFinished(view, url);
}
@Override
@ -162,13 +178,20 @@ public class WebViewLoginController extends BaseController {
// We use the URL user entered because one provided by the server is NOT reliable
userQueryDisposable = userUtils.createOrUpdateUser(loginData.getUsername(), loginData.getToken(),
baseUrl, null).subscribe(userEntity -> {
BundleBuilder bundleBuilder = new BundleBuilder(new Bundle());
bundleBuilder.putString(BundleKeys.KEY_USERNAME, userEntity.getUsername());
bundleBuilder.putString(BundleKeys.KEY_TOKEN, userEntity.getToken());
bundleBuilder.putString(BundleKeys.KEY_BASE_URL, userEntity.getBaseUrl());
getRouter().pushController(RouterTransaction.with(new AccountVerificationController
(bundleBuilder.build())).pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
if (!isPasswordUpdate) {
BundleBuilder bundleBuilder = new BundleBuilder(new Bundle());
bundleBuilder.putString(BundleKeys.KEY_USERNAME, userEntity.getUsername());
bundleBuilder.putString(BundleKeys.KEY_TOKEN, userEntity.getToken());
bundleBuilder.putString(BundleKeys.KEY_BASE_URL, userEntity.getBaseUrl());
getRouter().pushController(RouterTransaction.with(new AccountVerificationController
(bundleBuilder.build())).pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
} else {
getRouter().setRoot(RouterTransaction.with(new BottomNavigationController(R.menu.menu_navigation))
.pushChangeHandler(new HorizontalChangeHandler())
.popChangeHandler(new HorizontalChangeHandler()));
}
}, throwable -> dispose(),
this::dispose);
}

View File

@ -47,4 +47,19 @@
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="@dimen/small_item_height"
android:layout_height="@dimen/small_item_height"
android:layout_below="@id/text_field_boxes"
android:layout_centerInParent="true"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/padding_between_elements"
android:indeterminate="true"
android:progressTint="@color/colorPrimary"
android:visibility="invisible"/>
</RelativeLayout>

View File

@ -19,16 +19,29 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="@dimen/item_height"
android:layout_height="@dimen/item_height"
android:layout_centerInParent="true"
android:layout_marginEnd="@dimen/activity_horizontal_margin"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginStart="@dimen/activity_horizontal_margin"
android:indeterminate="true"
android:progressTint="@color/colorPrimary"/>
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:visibility="invisible">
</WebView>
</LinearLayout>
</RelativeLayout>

View File

@ -4,6 +4,7 @@
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="item_height">72dp</dimen>
<dimen name="small_item_height">24dp</dimen>
<dimen name="display_target_image_size">200dp</dimen>
<dimen name="display_target_image_margin">24dp</dimen>