Integrate Valere's remarks - step 1
This commit is contained in:
parent
85a4f83662
commit
a6541481bf
@ -95,8 +95,8 @@ class RxSession(private val session: Session) {
|
||||
return session.getPagedUsersLive(filter, excludedUserIds).asObservable()
|
||||
}
|
||||
|
||||
fun liveThreePIds(): Observable<List<ThreePid>> {
|
||||
return session.getThreePidsLive().asObservable()
|
||||
fun liveThreePIds(refreshData: Boolean): Observable<List<ThreePid>> {
|
||||
return session.getThreePidsLive(refreshData).asObservable()
|
||||
.startWithCallable { session.getThreePids() }
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ interface ProfileService {
|
||||
|
||||
/**
|
||||
* 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.task.Task
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface DeactivateAccountTask : Task<DeactivateAccountTask.Params, Unit> {
|
||||
@ -47,9 +48,8 @@ internal class DefaultDeactivateAccountTask @Inject constructor(
|
||||
}
|
||||
|
||||
// Logout from identity server if any, ignoring errors
|
||||
runCatching {
|
||||
identityDisconnectTask.execute(Unit)
|
||||
}
|
||||
runCatching { identityDisconnectTask.execute(Unit) }
|
||||
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||
|
||||
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.task.launchToCallback
|
||||
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
|
||||
import im.vector.matrix.android.internal.util.ensureProtocol
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.OkHttpClient
|
||||
@ -201,12 +202,7 @@ internal class DefaultIdentityService @Inject constructor(
|
||||
}
|
||||
|
||||
override fun setNewIdentityServer(url: String, callback: MatrixCallback<String>): Cancelable {
|
||||
val urlCandidate = buildString {
|
||||
if (!url.startsWith("http")) {
|
||||
append("https://")
|
||||
}
|
||||
append(url)
|
||||
}
|
||||
val urlCandidate = url.ensureProtocol()
|
||||
|
||||
return GlobalScope.launchToCallback(coroutineDispatchers.main, callback) {
|
||||
val current = getCurrentIdentityServerUrl()
|
||||
@ -217,9 +213,8 @@ internal class DefaultIdentityService @Inject constructor(
|
||||
// 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,
|
||||
// we will ask for a new token on the previous Identity server
|
||||
runCatching {
|
||||
identityDisconnectTask.execute(Unit)
|
||||
}
|
||||
runCatching { identityDisconnectTask.execute(Unit) }
|
||||
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||
|
||||
// Try to get a token
|
||||
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.
|
||||
*/
|
||||
@JvmField
|
||||
@Json(name = "algorithm")
|
||||
val algorithm: String,
|
||||
|
||||
/**
|
||||
* Required. The pepper from /hash_details. This is required even when the algorithm does not make use of it.
|
||||
*/
|
||||
@JvmField
|
||||
@Json(name = "pepper")
|
||||
val pepper: String
|
||||
)
|
||||
|
@ -88,11 +88,13 @@ internal class DefaultProfileService @Inject constructor(private val taskExecuto
|
||||
)
|
||||
}
|
||||
|
||||
override fun getThreePidsLive(): LiveData<List<ThreePid>> {
|
||||
// Force a refresh of the values
|
||||
refreshUserThreePidsTask
|
||||
.configureWith()
|
||||
.executeBy(taskExecutor)
|
||||
override fun getThreePidsLive(refreshData: Boolean): LiveData<List<ThreePid>> {
|
||||
if (refreshData) {
|
||||
// Force a refresh of the values
|
||||
refreshUserThreePidsTask
|
||||
.configureWith()
|
||||
.executeBy(taskExecutor)
|
||||
}
|
||||
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ 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.network.executeRequest
|
||||
import im.vector.matrix.android.internal.task.Task
|
||||
import im.vector.matrix.android.internal.util.awaitTransaction
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -38,7 +37,7 @@ internal class DefaultRefreshUserThreePidsTask @Inject constructor(private val p
|
||||
|
||||
Timber.d("Get ${accountThreePidsResponse.threePids?.size} threePids")
|
||||
// Store the list in DB
|
||||
monarchy.awaitTransaction { realm ->
|
||||
monarchy.writeAsync { realm ->
|
||||
realm.where(UserThreePidEntity::class.java).findAll().deleteAllFromRealm()
|
||||
accountThreePidsResponse.threePids?.forEach {
|
||||
val entity = UserThreePidEntity(
|
||||
|
@ -63,9 +63,9 @@ internal class DefaultSignOutTask @Inject constructor(
|
||||
}
|
||||
|
||||
// Logout from identity server if any
|
||||
runCatching {
|
||||
identityDisconnectTask.execute(Unit)
|
||||
}
|
||||
runCatching { identityDisconnectTask.execute(Unit) }
|
||||
.onFailure { Timber.w(it, "Unable to disconnect identity server") }
|
||||
|
||||
|
||||
Timber.d("SignOut: cleanup session...")
|
||||
cleanupSession.handle()
|
||||
|
@ -26,3 +26,14 @@ internal fun String.isValidUrl(): Boolean {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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?) {
|
||||
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()
|
||||
.colorizeMatchingText(getString(R.string.recovery_passphrase), colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
||||
.colorizeMatchingText(getString(R.string.message_key), colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
||||
.colorizeMatchingText(messageKey, color)
|
||||
.colorizeMatchingText(recoveryPassphrase, color)
|
||||
|
||||
// TODO: previous debouncing window was 600ms, check with Valere why
|
||||
recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() }
|
||||
|
||||
// TODO: previous debouncing window was 600ms, check with Valere why
|
||||
recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() }
|
||||
|
||||
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.platform.VectorBaseActivity
|
||||
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.SetIdentityServerViewModel
|
||||
import im.vector.riotx.features.terms.ReviewTermsActivity
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||
import javax.inject.Inject
|
||||
@ -108,7 +108,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
||||
navigator.openTerms(
|
||||
this,
|
||||
TermsService.ServiceType.IdentityService,
|
||||
SetIdentityServerViewModel.sanitatizeBaseURL(state.identityServer() ?: ""),
|
||||
state.identityServer()?.ensureProtocol() ?: "",
|
||||
null)
|
||||
}
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
|
||||
|
||||
private fun observeThreePids() {
|
||||
session.rx()
|
||||
.liveThreePIds()
|
||||
.liveThreePIds(true)
|
||||
.subscribe {
|
||||
retrieveBinding(it)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package im.vector.riotx.features.discovery
|
||||
|
||||
import android.view.KeyEvent
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.EditText
|
||||
import android.widget.TextView
|
||||
@ -37,6 +38,20 @@ abstract class SettingsEditTextItem : EpoxyModelWithHolder<SettingsEditTextItem.
|
||||
@EpoxyAttribute
|
||||
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) {
|
||||
super.bind(holder)
|
||||
holder.textView.setTextOrHide(descriptionText)
|
||||
@ -49,16 +64,8 @@ abstract class SettingsEditTextItem : EpoxyModelWithHolder<SettingsEditTextItem.
|
||||
holder.textInputLayout.error = errorText
|
||||
}
|
||||
|
||||
holder.editText.doOnTextChanged { code, _, _, _ ->
|
||||
code?.let { interactionListener?.onCodeChange(it.toString()) }
|
||||
}
|
||||
holder.editText.setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
interactionListener?.onValidate()
|
||||
return@setOnEditorActionListener true
|
||||
}
|
||||
return@setOnEditorActionListener false
|
||||
}
|
||||
holder.editText.doOnTextChanged(textChangeListener)
|
||||
holder.editText.setOnEditorActionListener(editorActionListener)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -122,7 +122,7 @@ class SetIdentityServerFragment @Inject constructor(
|
||||
navigator.openTerms(
|
||||
this,
|
||||
TermsService.ServiceType.IdentityService,
|
||||
SetIdentityServerViewModel.sanitatizeBaseURL(it.identityServerUrl),
|
||||
it.identityServerUrl,
|
||||
null)
|
||||
}
|
||||
}.exhaustive
|
||||
|
@ -31,6 +31,7 @@ import im.vector.riotx.core.di.HasScreenInjector
|
||||
import im.vector.riotx.core.extensions.exhaustive
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.core.utils.ensureProtocol
|
||||
|
||||
class SetIdentityServerViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: SetIdentityServerState,
|
||||
@ -59,14 +60,6 @@ class SetIdentityServerViewModel @AssistedInject constructor(
|
||||
val fragment: SetIdentityServerFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
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
|
||||
@ -90,14 +83,11 @@ class SetIdentityServerViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private fun doChangeIdentityServerUrl(url: String) {
|
||||
var baseUrl = url
|
||||
if (baseUrl.isEmpty()) {
|
||||
if (url.isEmpty()) {
|
||||
_viewEvents.post(SetIdentityServerViewEvents.Failure(R.string.settings_discovery_please_enter_server))
|
||||
return
|
||||
}
|
||||
baseUrl = sanitatizeBaseURL(baseUrl)
|
||||
|
||||
currentWantedUrl = baseUrl
|
||||
val baseUrl = url.ensureProtocol().also { currentWantedUrl = it }
|
||||
|
||||
_viewEvents.post(SetIdentityServerViewEvents.Loading())
|
||||
|
||||
|
@ -25,6 +25,7 @@ import butterknife.OnClick
|
||||
import com.jakewharton.rxbinding3.widget.textChanges
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.hideKeyboard
|
||||
import im.vector.riotx.core.utils.ensureProtocol
|
||||
import im.vector.riotx.core.utils.openUrlInExternalBrowser
|
||||
import kotlinx.android.synthetic.main.fragment_login_server_url_form.*
|
||||
import javax.inject.Inject
|
||||
@ -96,16 +97,13 @@ class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment()
|
||||
cleanupUi()
|
||||
|
||||
// Static check of homeserver url, empty, malformed, etc.
|
||||
var serverUrl = loginServerUrlFormHomeServerUrl.text.toString().trim()
|
||||
val serverUrl = loginServerUrlFormHomeServerUrl.text.toString().trim().ensureProtocol()
|
||||
|
||||
when {
|
||||
serverUrl.isBlank() -> {
|
||||
loginServerUrlFormHomeServerUrlTil.error = getString(R.string.login_error_invalid_home_server)
|
||||
}
|
||||
else -> {
|
||||
if (serverUrl.startsWith("http").not()) {
|
||||
serverUrl = "https://$serverUrl"
|
||||
}
|
||||
loginServerUrlFormHomeServerUrl.setText(serverUrl)
|
||||
loginViewModel.handle(LoginAction.UpdateHomeServer(serverUrl))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user