diff --git a/app/build.gradle b/app/build.gradle
index 30e53666c..6fa6fcaca 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -112,7 +112,7 @@ dependencies {
debugImplementation "javax.transaction:transaction-api:1.1-rev-1"
- implementation 'com.github.HITGIF:TextFieldBoxes:1.3.4'
+ implementation 'com.github.HITGIF:TextFieldBoxes:1.3.7'
implementation 'eu.davidea:flexible-adapter:5.0.0-rc3'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index dad231963..9b7f16ef8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -16,6 +16,7 @@
+
-
diff --git a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java
index 8e90df0eb..6de939146 100644
--- a/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java
+++ b/app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.java
@@ -20,9 +20,13 @@
*/
package com.nextcloud.talk.application;
+import android.annotation.SuppressLint;
import android.content.Context;
+import android.os.Build;
import android.support.multidex.MultiDex;
import android.support.multidex.MultiDexApplication;
+import android.support.v7.widget.AppCompatDrawableManager;
+import android.util.Log;
import com.evernote.android.job.JobManager;
import com.evernote.android.job.JobRequest;
@@ -39,6 +43,9 @@ import com.nextcloud.talk.utils.database.user.UserModule;
import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.security.GeneralSecurityException;
import javax.inject.Singleton;
@@ -76,6 +83,32 @@ public class NextcloudTalkApplication extends MultiDexApplication {
}
//endregion
+ //region private methods
+ // Solution inspired by https://stackoverflow.com/questions/34936590/why-isnt-my-vector-drawable-scaling-as-expected
+ private void useCompatVectorIfNeeded() {
+ int sdkInt = Build.VERSION.SDK_INT;
+ if (sdkInt == 21 || sdkInt == 22) {
+ try {
+ @SuppressLint("RestrictedApi") AppCompatDrawableManager drawableManager = AppCompatDrawableManager.get();
+ Class> inflateDelegateClass = Class.forName("android.support.v7.widget.AppCompatDrawableManager$InflateDelegate");
+ Class> vdcInflateDelegateClass = Class.forName("android.support.v7.widget.AppCompatDrawableManager$VdcInflateDelegate");
+
+ Constructor> constructor = vdcInflateDelegateClass.getDeclaredConstructor();
+ constructor.setAccessible(true);
+ Object vdcInflateDelegate = constructor.newInstance();
+
+ Class> args[] = {String.class, inflateDelegateClass};
+ Method addDelegate = AppCompatDrawableManager.class.getDeclaredMethod("addDelegate", args);
+ addDelegate.setAccessible(true);
+ addDelegate.invoke(drawableManager, "vector", vdcInflateDelegate);
+ } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException |
+ InvocationTargetException | IllegalAccessException e) {
+ Log.d(TAG, "Failed to use reflection to enable proper vector scaling");
+ }
+ }
+ }
+ //endregion
+
//region Overridden methods
@Override
public void onCreate() {
@@ -84,6 +117,8 @@ public class NextcloudTalkApplication extends MultiDexApplication {
FirebaseAnalytics.getInstance(this).setAnalyticsCollectionEnabled(false);
sharedApplication = this;
+ useCompatVectorIfNeeded();
+
try {
buildComponent();
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java b/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java
index 83924caac..372d18ba8 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.java
@@ -22,6 +22,9 @@ package com.nextcloud.talk.controllers;
import android.content.pm.ActivityInfo;
import android.support.annotation.NonNull;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -84,91 +87,130 @@ public class ServerSelectionController extends BaseController {
getActionBar().hide();
}
- textFieldBoxes.setLabelText(getResources().getString(R.string.nc_app_name) + " " + getResources().getString(R.string.nc_appended_server_url));
+ textFieldBoxes.setLabelText(getResources().getString(R.string.nc_server_url));
+ textFieldBoxes.getEndIconImageButton().setBackgroundDrawable(getResources().getDrawable(R.drawable
+ .ic_arrow_forward_white_24px));
+ textFieldBoxes.getEndIconImageButton().setAlpha(0.5f);
+ textFieldBoxes.getEndIconImageButton().setEnabled(false);
+ textFieldBoxes.getEndIconImageButton().setVisibility(View.VISIBLE);
+ textFieldBoxes.getEndIconImageButton().setOnClickListener(view1 -> checkServerAndProceed());
serverEntry.requestFocus();
+ serverEntry.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ if (!textFieldBoxes.isOnError() && !TextUtils.isEmpty(serverEntry.getText())) {
+ textFieldBoxes.getEndIconImageButton().setEnabled(true);
+ textFieldBoxes.getEndIconImageButton().setAlpha(1f);
+
+ } else {
+ textFieldBoxes.getEndIconImageButton().setEnabled(false);
+ textFieldBoxes.getEndIconImageButton().setAlpha(0.5f);
+ }
+ }
+ });
+
serverEntry.setOnEditorActionListener((textView, i, keyEvent) -> {
if (i == EditorInfo.IME_ACTION_DONE) {
- dispose();
-
- String url = serverEntry.getText().toString().trim();
-
- if (url.startsWith("http://") || url.startsWith("https://")) {
- serverEntry.setEnabled(false);
- progressBar.setVisibility(View.VISIBLE);
-
- if (url.endsWith("/")) {
- url = url.substring(0, url.length() - 1);
- }
-
- String queryUrl = url + ApiHelper.getUrlPostfixForStatus();
- final String finalServerUrl = url;
-
- statusQueryDisposable = ncApi.getServerStatus(queryUrl)
- .subscribeOn(Schedulers.newThread())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(status -> {
- String productName = getResources().getString(R.string.nc_server_product_name);
-
- if (status.isInstalled() && !status.isMaintenance() &&
- !status.isNeedsUpgrade() &&
- status.getVersion().startsWith("13.")) {
-
- getRouter().pushController(RouterTransaction.with(
- new WebViewLoginController(finalServerUrl, false))
- .pushChangeHandler(new HorizontalChangeHandler())
- .popChangeHandler(new HorizontalChangeHandler()));
- } else if (!status.isInstalled()) {
- textFieldBoxes.setError(String.format(
- getResources().getString(R.string.nc_server_not_installed), productName),
- true);
- } else if (status.isNeedsUpgrade()) {
- textFieldBoxes.setError(String.format(getResources().
- getString(R.string.nc_server_db_upgrade_needed),
- productName), true);
- } else if (status.isMaintenance()) {
- textFieldBoxes.setError(String.format(getResources().
- getString(R.string.nc_server_maintenance),
- productName),
- true);
- } else if (!status.getVersion().startsWith("13.")) {
- textFieldBoxes.setError(String.format(getResources().
- getString(R.string.nc_server_version),
- getResources().getString(R.string.nc_app_name)
- , productName), true);
- }
-
- }, throwable -> {
- if (throwable.getLocalizedMessage() != null) {
- textFieldBoxes.setError(throwable.getLocalizedMessage(), true);
- } else if (throwable.getCause() instanceof CertificateException) {
- textFieldBoxes.setError(getResources().getString(R.string.nc_certificate_error),
- true);
- }
- if (serverEntry != null) {
- serverEntry.setEnabled(true);
- }
- progressBar.setVisibility(View.GONE);
-
- dispose();
-
- }, () -> {
- progressBar.setVisibility(View.GONE);
- dispose();
- });
- } else {
- textFieldBoxes.setError(getResources().getString(R.string.nc_server_url_prefix), true);
- serverEntry.setEnabled(true);
- return true;
- }
-
+ checkServerAndProceed();
}
return false;
});
}
+ private void checkServerAndProceed() {
+ dispose();
+
+ String url = serverEntry.getText().toString().trim();
+
+ serverEntry.setEnabled(false);
+ progressBar.setVisibility(View.VISIBLE);
+
+ if (url.endsWith("/")) {
+ url = url.substring(0, url.length() - 1);
+ }
+
+ String queryUrl = url + ApiHelper.getUrlPostfixForStatus();
+
+ if (url.startsWith("http://") || url.startsWith("https://")) {
+ checkServer(queryUrl, false);
+ } else {
+ checkServer("https://" + queryUrl, true);
+ }
+ }
+
+ private void checkServer(String queryUrl, boolean checkForcedHttps) {
+ statusQueryDisposable = ncApi.getServerStatus(queryUrl)
+ .subscribeOn(Schedulers.newThread())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(status -> {
+ String productName = getResources().getString(R.string.nc_server_product_name);
+
+ if (status.isInstalled() && !status.isMaintenance() &&
+ !status.isNeedsUpgrade() &&
+ status.getVersion().startsWith("13.")) {
+
+ getRouter().pushController(RouterTransaction.with(
+ new WebViewLoginController(queryUrl.replace("/status.php", ""),
+ false))
+ .pushChangeHandler(new HorizontalChangeHandler())
+ .popChangeHandler(new HorizontalChangeHandler()));
+ } else if (!status.isInstalled()) {
+ textFieldBoxes.setError(String.format(
+ getResources().getString(R.string.nc_server_not_installed), productName),
+ true);
+ } else if (status.isNeedsUpgrade()) {
+ textFieldBoxes.setError(String.format(getResources().
+ getString(R.string.nc_server_db_upgrade_needed),
+ productName), true);
+ } else if (status.isMaintenance()) {
+ textFieldBoxes.setError(String.format(getResources().
+ getString(R.string.nc_server_maintenance),
+ productName),
+ true);
+ } else if (!status.getVersion().startsWith("13.")) {
+ textFieldBoxes.setError(String.format(getResources().
+ getString(R.string.nc_server_version),
+ getResources().getString(R.string.nc_app_name)
+ , productName), true);
+ }
+
+ }, throwable -> {
+ if (checkForcedHttps && (throwable instanceof Exception)) {
+ checkServer(queryUrl.replace("https://", "http://"), false);
+ } else {
+ if (throwable.getLocalizedMessage() != null) {
+ textFieldBoxes.setError(throwable.getLocalizedMessage(), true);
+ } else if (throwable.getCause() instanceof CertificateException) {
+ textFieldBoxes.setError(getResources().getString(R.string.nc_certificate_error),
+ true);
+ }
+
+ if (serverEntry != null) {
+ serverEntry.setEnabled(true);
+ }
+ progressBar.setVisibility(View.GONE);
+
+ dispose();
+ }
+ }, () -> {
+ progressBar.setVisibility(View.GONE);
+ dispose();
+ });
+ }
+
@Override
protected void onAttach(@NonNull View view) {
super.onAttach(view);
diff --git a/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java b/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
index 2cb46ccb9..848186995 100644
--- a/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
+++ b/app/src/main/java/com/nextcloud/talk/controllers/WebViewLoginController.java
@@ -245,7 +245,7 @@ public class WebViewLoginController extends BaseController {
// We use the URL user entered because one provided by the server is NOT reliable
ErrorMessageHolder.ErrorMessageType finalErrorMessageType = errorMessageType;
userQueryDisposable = userUtils.createOrUpdateUser(loginData.getUsername(), loginData.getToken(),
- baseUrl, null, null, true).
+ loginData.getServerUrl(), null, null, true).
subscribe(userEntity -> {
cookieManager.getCookieStore().removeAll();
if (!isPasswordUpdate && finalErrorMessageType == null) {
diff --git a/app/src/main/java/com/nextcloud/talk/utils/ColorUtils.java b/app/src/main/java/com/nextcloud/talk/utils/ColorUtils.java
index 2223ae9c3..7e4ab4580 100644
--- a/app/src/main/java/com/nextcloud/talk/utils/ColorUtils.java
+++ b/app/src/main/java/com/nextcloud/talk/utils/ColorUtils.java
@@ -20,6 +20,19 @@
package com.nextcloud.talk.utils;
+import android.content.res.Resources;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.ColorRes;
+import android.support.annotation.DrawableRes;
+
public class ColorUtils {
public static String colorSeed = "ballast butte permute doxy graham rummage grateful songbook pledge escapade";
+
+ public static Drawable getTintedDrawable(Resources res, @DrawableRes int drawableResId, @ColorRes int colorResId) {
+ Drawable drawable = res.getDrawable(drawableResId);
+ int color = res.getColor(colorResId);
+ drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+ return drawable;
+ }
}
diff --git a/app/src/main/res/drawable/ic_arrow_forward_white_24px.xml b/app/src/main/res/drawable/ic_arrow_forward_white_24px.xml
new file mode 100644
index 000000000..983307760
--- /dev/null
+++ b/app/src/main/res/drawable/ic_arrow_forward_white_24px.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/controller_server_selection.xml b/app/src/main/res/layout/controller_server_selection.xml
index 96636ec66..e197d89d7 100644
--- a/app/src/main/res/layout/controller_server_selection.xml
+++ b/app/src/main/res/layout/controller_server_selection.xml
@@ -23,7 +23,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/colorPrimary">
+ android:background="@color/colorPrimary"
+ android:fitsSystemWindows="true">
+ app:panelBackgroundColor="@color/colorPrimary"
+ app:primaryColor="@color/nc_white_color_complete">
@@ -65,14 +68,15 @@
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_centerHorizontal="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:layout_marginTop="24dp"
android:indeterminate="true"
- android:progressTint="@color/nc_white_color"
+ android:progressDrawable="@color/nc_white_color_complete"
+ android:progressTint="@color/nc_white_color_complete"
android:visibility="invisible"/>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b55312161..811188776 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5,7 +5,7 @@
Settings
- server address
+ Server address
Please enter http:// or https:// before the hostname
Please finish your %1$s installation
Please upgrade your %1$s database