diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java index 5eb481e164..a038b357c4 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -44,11 +44,11 @@ import com.nextcloud.talk.models.json.signaling.SignalingOverall; import com.nextcloud.talk.models.json.signaling.settings.SignalingSettingsOverall; import com.nextcloud.talk.models.json.status.StatusOverall; -import com.nextcloud.talk.translate.repositories.model.TranslationsOverall; import com.nextcloud.talk.models.json.unifiedsearch.UnifiedSearchOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileFieldsOverall; import com.nextcloud.talk.models.json.userprofile.UserProfileOverall; import com.nextcloud.talk.polls.repositories.model.PollOverall; +import com.nextcloud.talk.translate.repositories.model.TranslationsOverall; import java.util.List; import java.util.Map; @@ -358,6 +358,9 @@ Observable> setPassword2(@Header("Authorization") Strin @GET Observable getCapabilities(@Header("Authorization") String authorization, @Url String url); + @GET + Observable getCapabilities(@Url String url); + /* QueryMap items are as follows: - "lookIntoFuture": int (0 or 1), diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.kt index e433867764..aadc9a10f8 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ServerSelectionController.kt @@ -29,6 +29,7 @@ import android.net.Uri import android.os.Bundle import android.security.KeyChain import android.text.TextUtils +import android.util.Log import android.view.KeyEvent import android.view.View import android.view.inputmethod.EditorInfo @@ -44,6 +45,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedA import com.nextcloud.talk.controllers.base.BaseController import com.nextcloud.talk.controllers.util.viewBinding import com.nextcloud.talk.databinding.ControllerServerSelectionBinding +import com.nextcloud.talk.models.json.capabilities.CapabilitiesOverall import com.nextcloud.talk.models.json.generic.Status import com.nextcloud.talk.users.UserManager import com.nextcloud.talk.utils.AccountUtils @@ -51,7 +53,9 @@ import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.UriUtils import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_IS_ACCOUNT_IMPORT +import com.nextcloud.talk.utils.database.user.CapabilitiesUtilNew import com.nextcloud.talk.utils.singletons.ApplicationWideMessageHolder +import io.reactivex.Observer import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable import io.reactivex.schedulers.Schedulers @@ -203,7 +207,6 @@ class ServerSelectionController : private fun checkServerAndProceed() { dispose() var url: String = binding?.serverEntryTextInputEditText?.text.toString().trim { it <= ' ' } - binding?.serverEntryTextInputEditText?.isEnabled = false showserverEntryProgressBar() if (binding?.importOrChooseProviderText?.visibility != View.INVISIBLE) { binding?.importOrChooseProviderText?.visibility = View.INVISIBLE @@ -212,33 +215,27 @@ class ServerSelectionController : if (url.endsWith("/")) { url = url.substring(0, url.length - 1) } - val queryUrl = url + ApiUtils.getUrlPostfixForStatus() + if (UriUtils.hasHttpProtocollPrefixed(url)) { - checkServer(queryUrl, false) + checkServer(url, false) } else { - checkServer("https://$queryUrl", true) + checkServer("https://$url", true) } } - private fun checkServer(queryUrl: String, checkForcedHttps: Boolean) { - statusQueryDisposable = ncApi.getServerStatus(queryUrl) + private fun checkServer(url: String, checkForcedHttps: Boolean) { + val queryStatusUrl = url + ApiUtils.getUrlPostfixForStatus() + + statusQueryDisposable = ncApi.getServerStatus(queryStatusUrl) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ status: Status -> val productName = resources!!.getString(R.string.nc_server_product_name) val versionString: String = status.version!!.substring(0, status.version!!.indexOf(".")) val version: Int = versionString.toInt() + if (isServerStatusQueryable(status) && version >= MIN_SERVER_MAJOR_VERSION) { - router.pushController( - RouterTransaction.with( - WebViewLoginController( - queryUrl.replace("/status.php", ""), - false - ) - ) - .pushChangeHandler(HorizontalChangeHandler()) - .popChangeHandler(HorizontalChangeHandler()) - ) + findServerTalkApp(url) } else if (!status.installed) { setErrorText( String.format( @@ -271,7 +268,7 @@ class ServerSelectionController : } }, { throwable: Throwable -> if (checkForcedHttps) { - checkServer(queryUrl.replace("https://", "http://"), false) + checkServer(queryStatusUrl.replace("https://", "http://"), false) } else { if (throwable.localizedMessage != null) { setErrorText(throwable.localizedMessage) @@ -281,8 +278,6 @@ class ServerSelectionController : hideserverEntryProgressBar() } - binding?.serverEntryTextInputEditText?.isEnabled = true - if (binding?.importOrChooseProviderText?.visibility != View.INVISIBLE) { binding?.importOrChooseProviderText?.visibility = View.VISIBLE binding?.certTextView?.visibility = View.VISIBLE @@ -299,23 +294,82 @@ class ServerSelectionController : } } + private fun findServerTalkApp(queryUrl: String) { + ncApi.getCapabilities(ApiUtils.getUrlForCapabilities(queryUrl)) + .subscribeOn(Schedulers.io()) + .subscribe(object : Observer { + override fun onSubscribe(d: Disposable) { + } + + override fun onNext(capabilitiesOverall: CapabilitiesOverall) { + val capabilities = capabilitiesOverall.ocs?.data?.capabilities + + val hasTalk = + capabilities?.spreedCapability != null && + capabilities.spreedCapability?.features != null && + capabilities.spreedCapability?.features?.isNotEmpty() == true + + if (hasTalk) { + activity?.runOnUiThread { + if (CapabilitiesUtilNew.isServerEOL(capabilities)) { + if (resources != null) { + activity!!.runOnUiThread { + setErrorText(resources!!.getString(R.string.nc_settings_server_eol)) + } + } + } else { + router.pushController( + RouterTransaction.with( + WebViewLoginController( + queryUrl.replace("/status.php", ""), + false + ) + ) + .pushChangeHandler(HorizontalChangeHandler()) + .popChangeHandler(HorizontalChangeHandler()) + ) + } + } + } else { + if (activity != null && resources != null) { + activity!!.runOnUiThread { + setErrorText(resources!!.getString(R.string.nc_server_unsupported)) + } + } + } + } + + override fun onError(e: Throwable) { + Log.e(TAG, "Error while checking capabilities", e) + if (activity != null && resources != null) { + activity!!.runOnUiThread { + setErrorText(resources!!.getString(R.string.nc_common_error_sorry)) + } + } + } + + override fun onComplete() { + // unused atm + } + }) + } + private fun isServerStatusQueryable(status: Status): Boolean { return status.installed && !status.maintenance && !status.needsUpgrade } private fun setErrorText(text: String) { + binding?.errorWrapper?.visibility = View.VISIBLE binding?.errorText?.text = text - binding?.errorText?.visibility = View.VISIBLE - binding?.serverEntryProgressBar?.visibility = View.GONE + hideserverEntryProgressBar() } private fun showserverEntryProgressBar() { - binding?.errorText?.visibility = View.GONE + binding?.errorWrapper?.visibility = View.INVISIBLE binding?.serverEntryProgressBar?.visibility = View.VISIBLE } private fun hideserverEntryProgressBar() { - binding?.errorText?.visibility = View.GONE binding?.serverEntryProgressBar?.visibility = View.INVISIBLE } diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 74b45f7868..abd41f8376 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -233,7 +233,7 @@ class ConversationsListActivity : } currentUser = userManager.currentUser.blockingGet() if (currentUser != null) { - if (isServerEOL(currentUser!!)) { + if (isServerEOL(currentUser!!.capabilities)) { showServerEOLDialog() return } diff --git a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt index 23f0ddb40e..7e24d1feb2 100644 --- a/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/settings/SettingsActivity.kt @@ -621,7 +621,7 @@ class SettingsActivity : BaseActivity() { private fun setupServerAgeWarning() { when { - CapabilitiesUtilNew.isServerEOL(currentUser!!) -> { + CapabilitiesUtilNew.isServerEOL(currentUser!!.capabilities) -> { binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context), R.color.nc_darkRed)) binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol) binding.serverAgeWarningIcon.setColorFilter( diff --git a/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt b/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt index d8ef399f9e..96915cc51b 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt +++ b/app/src/main/java/com/nextcloud/talk/utils/database/user/CapabilitiesUtilNew.kt @@ -22,6 +22,7 @@ package com.nextcloud.talk.utils.database.user import com.nextcloud.talk.data.user.model.User +import com.nextcloud.talk.models.json.capabilities.Capabilities @Suppress("TooManyFunctions") object CapabilitiesUtilNew { @@ -37,9 +38,9 @@ object CapabilitiesUtilNew { } @JvmStatic - fun isServerEOL(user: User): Boolean { + fun isServerEOL(capabilities: Capabilities?): Boolean { // Capability is available since Talk 4 => Nextcloud 14 => Autmn 2018 - return !hasSpreedFeatureCapability(user, "no-ping") + return !hasSpreedFeatureCapability(capabilities, "no-ping") } fun isServerAlmostEOL(user: User): Boolean { @@ -57,8 +58,13 @@ object CapabilitiesUtilNew { @JvmStatic fun hasSpreedFeatureCapability(user: User?, capabilityName: String): Boolean { - if (user?.capabilities?.spreedCapability?.features != null) { - return user.capabilities!!.spreedCapability!!.features!!.contains(capabilityName) + return hasSpreedFeatureCapability(user?.capabilities, capabilityName) + } + + @JvmStatic + fun hasSpreedFeatureCapability(capabilities: Capabilities?, capabilityName: String): Boolean { + if (capabilities?.spreedCapability?.features != null) { + return capabilities.spreedCapability!!.features!!.contains(capabilityName) } return false } diff --git a/app/src/main/res/layout/controller_server_selection.xml b/app/src/main/res/layout/controller_server_selection.xml index 68a5356c5d..e7d9cfaf0f 100644 --- a/app/src/main/res/layout/controller_server_selection.xml +++ b/app/src/main/res/layout/controller_server_selection.xml @@ -133,23 +133,37 @@ - + android:orientation="horizontal" + tools:visibility="visible"> + + + + + +