mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-25 23:39:00 +03:00
Integrate Valere's remarks - step 1
This commit is contained in:
parent
85a4f83662
commit
a6541481bf
17 changed files with 76 additions and 65 deletions
matrix-sdk-android-rx/src/main/java/im/vector/matrix/rx
matrix-sdk-android/src/main/java/im/vector/matrix/android
api/session/profile
internal
session
account
identity
profile
signout
util
vector/src/main/java/im/vector/riotx
|
@ -95,8 +95,8 @@ class RxSession(private val session: Session) {
|
||||||
return session.getPagedUsersLive(filter, excludedUserIds).asObservable()
|
return session.getPagedUsersLive(filter, excludedUserIds).asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveThreePIds(): Observable<List<ThreePid>> {
|
fun liveThreePIds(refreshData: Boolean): Observable<List<ThreePid>> {
|
||||||
return session.getThreePidsLive().asObservable()
|
return session.getThreePidsLive(refreshData).asObservable()
|
||||||
.startWithCallable { session.getThreePids() }
|
.startWithCallable { session.getThreePids() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ interface ProfileService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current user 3Pids Live
|
* Get the current user 3Pids Live
|
||||||
|
* @param refreshData set to true to fetch data from the homeserver
|
||||||
*/
|
*/
|
||||||
fun getThreePidsLive(): LiveData<List<ThreePid>>
|
fun getThreePidsLive(refreshData: Boolean): LiveData<List<ThreePid>>
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import im.vector.matrix.android.internal.session.cleanup.CleanupSession
|
||||||
import im.vector.matrix.android.internal.session.identity.IdentityDisconnectTask
|
import im.vector.matrix.android.internal.session.identity.IdentityDisconnectTask
|
||||||
import im.vector.matrix.android.internal.task.Task
|
import im.vector.matrix.android.internal.task.Task
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
|
internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
|
||||||
|
@ -47,9 +48,8 @@ internal class DefaultDeactivateAccountTask @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logout from identity server if any, ignoring errors
|
// Logout from identity server if any, ignoring errors
|
||||||
runCatching {
|
runCatching { identityDisconnectTask.execute(Unit) }
|
||||||
identityDisconnectTask.execute(Unit)
|
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||||
}
|
|
||||||
|
|
||||||
cleanupSession.handle()
|
cleanupSession.handle()
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import im.vector.matrix.android.internal.session.sync.model.accountdata.UserAcco
|
||||||
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
|
import im.vector.matrix.android.internal.session.user.accountdata.UpdateUserAccountDataTask
|
||||||
import im.vector.matrix.android.internal.task.launchToCallback
|
import im.vector.matrix.android.internal.task.launchToCallback
|
||||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||||
|
import im.vector.matrix.android.internal.util.ensureProtocol
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
|
@ -201,12 +202,7 @@ internal class DefaultIdentityService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setNewIdentityServer(url: String, callback: MatrixCallback<String>): Cancelable {
|
override fun setNewIdentityServer(url: String, callback: MatrixCallback<String>): Cancelable {
|
||||||
val urlCandidate = buildString {
|
val urlCandidate = url.ensureProtocol()
|
||||||
if (!url.startsWith("http")) {
|
|
||||||
append("https://")
|
|
||||||
}
|
|
||||||
append(url)
|
|
||||||
}
|
|
||||||
|
|
||||||
return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) {
|
return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) {
|
||||||
val current = getCurrentIdentityServerUrl()
|
val current = getCurrentIdentityServerUrl()
|
||||||
|
@ -217,9 +213,8 @@ internal class DefaultIdentityService @Inject constructor(
|
||||||
// Disconnect previous one if any, first, because the token will change.
|
// Disconnect previous one if any, first, because the token will change.
|
||||||
// In case of error when configuring the new identity server, this is not a big deal,
|
// In case of error when configuring the new identity server, this is not a big deal,
|
||||||
// we will ask for a new token on the previous Identity server
|
// we will ask for a new token on the previous Identity server
|
||||||
runCatching {
|
runCatching { identityDisconnectTask.execute(Unit) }
|
||||||
identityDisconnectTask.execute(Unit)
|
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||||
}
|
|
||||||
|
|
||||||
// Try to get a token
|
// Try to get a token
|
||||||
val token = getNewIdentityServerToken(urlCandidate)
|
val token = getNewIdentityServerToken(urlCandidate)
|
||||||
|
|
|
@ -34,14 +34,12 @@ internal data class IdentityLookUpParams(
|
||||||
/**
|
/**
|
||||||
* Required. The algorithm the client is using to encode the addresses. This should be one of the available options from /hash_details.
|
* Required. The algorithm the client is using to encode the addresses. This should be one of the available options from /hash_details.
|
||||||
*/
|
*/
|
||||||
@JvmField
|
|
||||||
@Json(name = "algorithm")
|
@Json(name = "algorithm")
|
||||||
val algorithm: String,
|
val algorithm: String,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required. The pepper from /hash_details. This is required even when the algorithm does not make use of it.
|
* Required. The pepper from /hash_details. This is required even when the algorithm does not make use of it.
|
||||||
*/
|
*/
|
||||||
@JvmField
|
|
||||||
@Json(name = "pepper")
|
@Json(name = "pepper")
|
||||||
val pepper: String
|
val pepper: String
|
||||||
)
|
)
|
||||||
|
|
|
@ -88,11 +88,13 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getThreePidsLive(): LiveData<List<ThreePid>> {
|
override fun getThreePidsLive(refreshData: Boolean): LiveData<List<ThreePid>> {
|
||||||
// Force a refresh of the values
|
if (refreshData) {
|
||||||
refreshUserThreePidsTask
|
// Force a refresh of the values
|
||||||
.configureWith()
|
refreshUserThreePidsTask
|
||||||
.executeBy(taskExecutor)
|
.configureWith()
|
||||||
|
.executeBy(taskExecutor)
|
||||||
|
}
|
||||||
|
|
||||||
return monarchy.findAllMappedWithChanges(
|
return monarchy.findAllMappedWithChanges(
|
||||||
{ it.where<UserThreePidEntity>() },
|
{ it.where<UserThreePidEntity>() },
|
||||||
|
|
|
@ -20,7 +20,6 @@ import com.zhuinden.monarchy.Monarchy
|
||||||
import im.vector.matrix.android.internal.database.model.UserThreePidEntity
|
import im.vector.matrix.android.internal.database.model.UserThreePidEntity
|
||||||
import im.vector.matrix.android.internal.network.executeRequest
|
import im.vector.matrix.android.internal.network.executeRequest
|
||||||
import im.vector.matrix.android.internal.task.Task
|
import im.vector.matrix.android.internal.task.Task
|
||||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -38,7 +37,7 @@ internal class DefaultRefreshUserThreePidsTask @Inject constructor(private val p
|
||||||
|
|
||||||
Timber.d("Get ${accountThreePidsResponse.threePids?.size} threePids")
|
Timber.d("Get ${accountThreePidsResponse.threePids?.size} threePids")
|
||||||
// Store the list in DB
|
// Store the list in DB
|
||||||
monarchy.awaitTransaction { realm ->
|
monarchy.writeAsync { realm ->
|
||||||
realm.where(UserThreePidEntity::class.java).findAll().deleteAllFromRealm()
|
realm.where(UserThreePidEntity::class.java).findAll().deleteAllFromRealm()
|
||||||
accountThreePidsResponse.threePids?.forEach {
|
accountThreePidsResponse.threePids?.forEach {
|
||||||
val entity = UserThreePidEntity(
|
val entity = UserThreePidEntity(
|
||||||
|
|
|
@ -63,9 +63,9 @@ internal class DefaultSignOutTask @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logout from identity server if any
|
// Logout from identity server if any
|
||||||
runCatching {
|
runCatching { identityDisconnectTask.execute(Unit) }
|
||||||
identityDisconnectTask.execute(Unit)
|
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||||
}
|
|
||||||
|
|
||||||
Timber.d("SignOut: cleanup session...")
|
Timber.d("SignOut: cleanup session...")
|
||||||
cleanupSession.handle()
|
cleanupSession.handle()
|
||||||
|
|
|
@ -26,3 +26,14 @@ internal fun String.isValidUrl(): Boolean {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure string starts with "http". If it is not the case, "https://" is added, only if the String is not empty
|
||||||
|
*/
|
||||||
|
internal fun String.ensureProtocol(): String {
|
||||||
|
return when {
|
||||||
|
isEmpty() -> this
|
||||||
|
!startsWith("http") -> "https://$this"
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,3 +26,14 @@ fun String.isValidUrl(): Boolean {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure string starts with "http". If it is not the case, "https://" is added, only if the String is not empty
|
||||||
|
*/
|
||||||
|
internal fun String.ensureProtocol(): String {
|
||||||
|
return when {
|
||||||
|
isEmpty() -> this
|
||||||
|
!startsWith("http") -> "https://$this"
|
||||||
|
else -> this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,17 +48,16 @@ class BootstrapSaveRecoveryKeyFragment @Inject constructor(
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
bootstrapSaveText.text = getString(R.string.bootstrap_save_key_description, getString(R.string.message_key), getString(R.string.recovery_passphrase))
|
val messageKey = getString(R.string.message_key)
|
||||||
|
val recoveryPassphrase = getString(R.string.recovery_passphrase)
|
||||||
|
val color = colorProvider.getColorFromAttribute(R.attr.vctr_toolbar_link_text_color)
|
||||||
|
bootstrapSaveText.text = getString(R.string.bootstrap_save_key_description, messageKey, recoveryPassphrase)
|
||||||
.toSpannable()
|
.toSpannable()
|
||||||
.colorizeMatchingText(getString(R.string.recovery_passphrase), colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
.colorizeMatchingText(messageKey, color)
|
||||||
.colorizeMatchingText(getString(R.string.message_key), colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
.colorizeMatchingText(recoveryPassphrase, color)
|
||||||
|
|
||||||
// TODO: previous debouncing window was 600ms, check with Valere why
|
|
||||||
recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() }
|
recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() }
|
||||||
|
|
||||||
// TODO: previous debouncing window was 600ms, check with Valere why
|
|
||||||
recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() }
|
recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() }
|
||||||
|
|
||||||
recoveryContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.GoToCompleted) }
|
recoveryContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.GoToCompleted) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ import im.vector.riotx.core.extensions.exhaustive
|
||||||
import im.vector.riotx.core.extensions.observeEvent
|
import im.vector.riotx.core.extensions.observeEvent
|
||||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
|
import im.vector.riotx.core.utils.ensureProtocol
|
||||||
import im.vector.riotx.features.discovery.change.SetIdentityServerFragment
|
import im.vector.riotx.features.discovery.change.SetIdentityServerFragment
|
||||||
import im.vector.riotx.features.discovery.change.SetIdentityServerViewModel
|
|
||||||
import im.vector.riotx.features.terms.ReviewTermsActivity
|
import im.vector.riotx.features.terms.ReviewTermsActivity
|
||||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -108,7 +108,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
||||||
navigator.openTerms(
|
navigator.openTerms(
|
||||||
this,
|
this,
|
||||||
TermsService.ServiceType.IdentityService,
|
TermsService.ServiceType.IdentityService,
|
||||||
SetIdentityServerViewModel.sanitatizeBaseURL(state.identityServer() ?: ""),
|
state.identityServer()?.ensureProtocol() ?: "",
|
||||||
null)
|
null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
private fun observeThreePids() {
|
private fun observeThreePids() {
|
||||||
session.rx()
|
session.rx()
|
||||||
.liveThreePIds()
|
.liveThreePIds(true)
|
||||||
.subscribe {
|
.subscribe {
|
||||||
retrieveBinding(it)
|
retrieveBinding(it)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.riotx.features.discovery
|
package im.vector.riotx.features.discovery
|
||||||
|
|
||||||
|
import android.view.KeyEvent
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -37,6 +38,20 @@ abstract class SettingsEditTextItem : EpoxyModelWithHolder<SettingsEditTextItem.
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var interactionListener: Listener? = null
|
var interactionListener: Listener? = null
|
||||||
|
|
||||||
|
private val textChangeListener: (text: CharSequence?, start: Int, count: Int, after: Int) -> Unit = { code, _, _, _ ->
|
||||||
|
code?.let { interactionListener?.onCodeChange(it.toString()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val editorActionListener = object : TextView.OnEditorActionListener {
|
||||||
|
override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
|
interactionListener?.onValidate()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
super.bind(holder)
|
super.bind(holder)
|
||||||
holder.textView.setTextOrHide(descriptionText)
|
holder.textView.setTextOrHide(descriptionText)
|
||||||
|
@ -49,16 +64,8 @@ abstract class SettingsEditTextItem : EpoxyModelWithHolder<SettingsEditTextItem.
|
||||||
holder.textInputLayout.error = errorText
|
holder.textInputLayout.error = errorText
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.editText.doOnTextChanged { code, _, _, _ ->
|
holder.editText.doOnTextChanged(textChangeListener)
|
||||||
code?.let { interactionListener?.onCodeChange(it.toString()) }
|
holder.editText.setOnEditorActionListener(editorActionListener)
|
||||||
}
|
|
||||||
holder.editText.setOnEditorActionListener { _, actionId, _ ->
|
|
||||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
|
||||||
interactionListener?.onValidate()
|
|
||||||
return@setOnEditorActionListener true
|
|
||||||
}
|
|
||||||
return@setOnEditorActionListener false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder : VectorEpoxyHolder() {
|
class Holder : VectorEpoxyHolder() {
|
||||||
|
|
|
@ -122,7 +122,7 @@ class SetIdentityServerFragment @Inject constructor(
|
||||||
navigator.openTerms(
|
navigator.openTerms(
|
||||||
this,
|
this,
|
||||||
TermsService.ServiceType.IdentityService,
|
TermsService.ServiceType.IdentityService,
|
||||||
SetIdentityServerViewModel.sanitatizeBaseURL(it.identityServerUrl),
|
it.identityServerUrl,
|
||||||
null)
|
null)
|
||||||
}
|
}
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
|
|
|
@ -31,6 +31,7 @@ import im.vector.riotx.core.di.HasScreenInjector
|
||||||
import im.vector.riotx.core.extensions.exhaustive
|
import im.vector.riotx.core.extensions.exhaustive
|
||||||
import im.vector.riotx.core.platform.VectorViewModel
|
import im.vector.riotx.core.platform.VectorViewModel
|
||||||
import im.vector.riotx.core.resources.StringProvider
|
import im.vector.riotx.core.resources.StringProvider
|
||||||
|
import im.vector.riotx.core.utils.ensureProtocol
|
||||||
|
|
||||||
class SetIdentityServerViewModel @AssistedInject constructor(
|
class SetIdentityServerViewModel @AssistedInject constructor(
|
||||||
@Assisted initialState: SetIdentityServerState,
|
@Assisted initialState: SetIdentityServerState,
|
||||||
|
@ -59,14 +60,6 @@ class SetIdentityServerViewModel @AssistedInject constructor(
|
||||||
val fragment: SetIdentityServerFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
val fragment: SetIdentityServerFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||||
return fragment.viewModelFactory.create(state)
|
return fragment.viewModelFactory.create(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sanitatizeBaseURL(baseUrl: String): String {
|
|
||||||
var baseUrl1 = baseUrl
|
|
||||||
if (!baseUrl1.startsWith("http://") && !baseUrl1.startsWith("https://")) {
|
|
||||||
baseUrl1 = "https://$baseUrl1"
|
|
||||||
}
|
|
||||||
return baseUrl1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentWantedUrl: String? = null
|
var currentWantedUrl: String? = null
|
||||||
|
@ -90,14 +83,11 @@ class SetIdentityServerViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun doChangeIdentityServerUrl(url: String) {
|
private fun doChangeIdentityServerUrl(url: String) {
|
||||||
var baseUrl = url
|
if (url.isEmpty()) {
|
||||||
if (baseUrl.isEmpty()) {
|
|
||||||
_viewEvents.post(SetIdentityServerViewEvents.Failure(R.string.settings_discovery_please_enter_server))
|
_viewEvents.post(SetIdentityServerViewEvents.Failure(R.string.settings_discovery_please_enter_server))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
baseUrl = sanitatizeBaseURL(baseUrl)
|
val baseUrl = url.ensureProtocol().also { currentWantedUrl = it }
|
||||||
|
|
||||||
currentWantedUrl = baseUrl
|
|
||||||
|
|
||||||
_viewEvents.post(SetIdentityServerViewEvents.Loading())
|
_viewEvents.post(SetIdentityServerViewEvents.Loading())
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import butterknife.OnClick
|
||||||
import com.jakewharton.rxbinding3.widget.textChanges
|
import com.jakewharton.rxbinding3.widget.textChanges
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.extensions.hideKeyboard
|
import im.vector.riotx.core.extensions.hideKeyboard
|
||||||
|
import im.vector.riotx.core.utils.ensureProtocol
|
||||||
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
||||||
import kotlinx.android.synthetic.main.fragment_login_server_url_form.*
|
import kotlinx.android.synthetic.main.fragment_login_server_url_form.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -96,16 +97,13 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment()
|
||||||
cleanupUi()
|
cleanupUi()
|
||||||
|
|
||||||
// Static check of homeserver url, empty, malformed, etc.
|
// Static check of homeserver url, empty, malformed, etc.
|
||||||
var serverUrl = loginServerUrlFormHomeServerUrl.text.toString().trim()
|
val serverUrl = loginServerUrlFormHomeServerUrl.text.toString().trim().ensureProtocol()
|
||||||
|
|
||||||
when {
|
when {
|
||||||
serverUrl.isBlank() -> {
|
serverUrl.isBlank() -> {
|
||||||
loginServerUrlFormHomeServerUrlTil.error = getString(R.string.login_error_invalid_home_server)
|
loginServerUrlFormHomeServerUrlTil.error = getString(R.string.login_error_invalid_home_server)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
if (serverUrl.startsWith("http").not()) {
|
|
||||||
serverUrl = "https://$serverUrl"
|
|
||||||
}
|
|
||||||
loginServerUrlFormHomeServerUrl.setText(serverUrl)
|
loginServerUrlFormHomeServerUrl.setText(serverUrl)
|
||||||
loginViewModel.handle(LoginAction.UpdateHomeServer(serverUrl))
|
loginViewModel.handle(LoginAction.UpdateHomeServer(serverUrl))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue