Integrate Valere's remarks - step 1

This commit is contained in:
Benoit Marty 2020-05-15 18:54:12 +02:00
parent 85a4f83662
commit a6541481bf
17 changed files with 76 additions and 65 deletions

View File

@ -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() }
}

View File

@ -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>>
}

View File

@ -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()
}

View File

@ -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)

View File

@ -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
)

View File

@ -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>() },

View File

@ -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(

View File

@ -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()

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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) }
}

View File

@ -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)
}
}

View File

@ -77,7 +77,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
private fun observeThreePids() {
session.rx()
.liveThreePIds()
.liveThreePIds(true)
.subscribe {
retrieveBinding(it)
}

View File

@ -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() {

View File

@ -122,7 +122,7 @@ class SetIdentityServerFragment @Inject constructor(
navigator.openTerms(
this,
TermsService.ServiceType.IdentityService,
SetIdentityServerViewModel.sanitatizeBaseURL(it.identityServerUrl),
it.identityServerUrl,
null)
}
}.exhaustive

View File

@ -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())

View File

@ -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))
}