Merge pull request #3128 from vector-im/feature/bma/various_fixes

Various fixes before release 1.1.4
This commit is contained in:
Benoit Marty 2021-04-07 15:32:13 +02:00 committed by GitHub
commit 0693ce13e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 73 additions and 50 deletions

View File

@ -16,6 +16,7 @@ Improvements 🙌:
- Improve timeline filtering (dissociate membership and profile events, display hidden events when highlighted, fix hidden item/read receipts behavior) - Improve timeline filtering (dissociate membership and profile events, display hidden events when highlighted, fix hidden item/read receipts behavior)
- Add better support for empty room name fallback (#3106) - Add better support for empty room name fallback (#3106)
- Room list improvements (paging) - Room list improvements (paging)
- Fix quick click action (#3127)
Bugfix 🐛: Bugfix 🐛:
- Fix bad theme change for the MainActivity - Fix bad theme change for the MainActivity
@ -23,6 +24,7 @@ Bugfix 🐛:
- Disable URL preview for some domains (#2995) - Disable URL preview for some domains (#2995)
- Fix avatar rendering for DMs, after initial sync (#2693) - Fix avatar rendering for DMs, after initial sync (#2693)
- Fix mandatory parameter in API (#3065) - Fix mandatory parameter in API (#3065)
- If signout request fails, do not start LoginActivity, but restart the app (#3099)
Translations 🗣: Translations 🗣:
- -

View File

@ -35,5 +35,5 @@ object MessageType {
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
const val MSGTYPE_CONFETTI = "nic.custom.confetti" const val MSGTYPE_CONFETTI = "nic.custom.confetti"
const val MSGTYPE_SNOW = "nic.custom.snow" const val MSGTYPE_SNOW = "io.element.effect.snowfall"
} }

View File

@ -55,9 +55,13 @@ internal suspend inline fun <DATA> executeRequest(globalErrorReceiver: GlobalErr
else -> throwable else -> throwable
} }
// Log some details about the request which has failed. This is less useful than before... // Log some details about the request which has failed.
// Timber.e("Exception when executing request ${apiCall.request().method} ${apiCall.request().url.toString().substringBefore("?")}") val request = (throwable as? HttpException)?.response()?.raw()?.request
if (request == null) {
Timber.e("Exception when executing request") Timber.e("Exception when executing request")
} else {
Timber.e("Exception when executing request ${request.method} ${request.url.toString().substringBefore("?")}")
}
// Check if this is a certificateException // Check if this is a certificateException
CertUtil.getCertificateException(exception) CertUtil.getCertificateException(exception)

View File

@ -604,12 +604,14 @@ internal class DefaultTimeline(
return offsetResults.size return offsetResults.size
} }
private fun buildTimelineEvent(eventEntity: TimelineEventEntity) = timelineEventMapper.map( private fun buildTimelineEvent(eventEntity: TimelineEventEntity): TimelineEvent {
return timelineEventMapper.map(
timelineEventEntity = eventEntity, timelineEventEntity = eventEntity,
buildReadReceipts = settings.buildReadReceipts buildReadReceipts = settings.buildReadReceipts
).let { ).let { timelineEvent ->
// eventually enhance with ui echo? // eventually enhance with ui echo?
(uiEchoManager.decorateEventWithReactionUiEcho(it) ?: it) uiEchoManager.decorateEventWithReactionUiEcho(timelineEvent) ?: timelineEvent
}
} }
/** /**

View File

@ -15,6 +15,8 @@
*/ */
package im.vector.app.core.utils package im.vector.app.core.utils
import android.os.SystemClock
/** /**
* Simple ThrottleFirst * Simple ThrottleFirst
* See https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/throttleFirst.png * See https://raw.githubusercontent.com/wiki/ReactiveX/RxJava/images/rx-operators/throttleFirst.png
@ -23,7 +25,7 @@ class FirstThrottler(private val minimumInterval: Long = 800) {
private var lastDate = 0L private var lastDate = 0L
fun canHandle(): Boolean { fun canHandle(): Boolean {
val now = System.currentTimeMillis() val now = SystemClock.elapsedRealtime()
if (now > lastDate + minimumInterval) { if (now > lastDate + minimumInterval) {
lastDate = now lastDate = now
return true return true

View File

@ -161,25 +161,22 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
lifecycleScope.launch { lifecycleScope.launch {
try { try {
session.signOut(!args.isUserLoggedOut) session.signOut(!args.isUserLoggedOut)
} catch (failure: Throwable) {
displayError(failure)
return@launch
}
Timber.w("SIGN_OUT: success, start app") Timber.w("SIGN_OUT: success, start app")
sessionHolder.clearActiveSession() sessionHolder.clearActiveSession()
doLocalCleanup(clearPreferences = true) doLocalCleanup(clearPreferences = true)
startNextActivityAndFinish() startNextActivityAndFinish()
} catch (failure: Throwable) {
displayError(failure)
}
} }
} }
args.clearCache -> { args.clearCache -> {
lifecycleScope.launch { lifecycleScope.launch {
try {
session.clearCache() session.clearCache()
doLocalCleanup(clearPreferences = false) doLocalCleanup(clearPreferences = false)
session.startSyncing(applicationContext) session.startSyncing(applicationContext)
startNextActivityAndFinish() startNextActivityAndFinish()
} catch (failure: Throwable) {
displayError(failure)
}
} }
} }
} }
@ -215,15 +212,16 @@ class MainActivity : VectorBaseActivity<ActivityMainBinding>(), UnlockedActivity
.setTitle(R.string.dialog_title_error) .setTitle(R.string.dialog_title_error)
.setMessage(errorFormatter.toHumanReadable(failure)) .setMessage(errorFormatter.toHumanReadable(failure))
.setPositiveButton(R.string.global_retry) { _, _ -> doCleanUp() } .setPositiveButton(R.string.global_retry) { _, _ -> doCleanUp() }
.setNegativeButton(R.string.cancel) { _, _ -> startNextActivityAndFinish() } .setNegativeButton(R.string.cancel) { _, _ -> startNextActivityAndFinish(ignoreClearCredentials = true) }
.setCancelable(false) .setCancelable(false)
.show() .show()
} }
} }
private fun startNextActivityAndFinish() { private fun startNextActivityAndFinish(ignoreClearCredentials: Boolean = false) {
val intent = when { val intent = when {
args.clearCredentials args.clearCredentials
&& !ignoreClearCredentials
&& (!args.isUserLoggedOut || args.isAccountDeactivated) -> && (!args.isUserLoggedOut || args.isAccountDeactivated) ->
// User has explicitly asked to log out or deactivated his account // User has explicitly asked to log out or deactivated his account
LoginActivity.newIntent(this, null) LoginActivity.newIntent(this, null)

View File

@ -1675,10 +1675,12 @@ class RoomDetailFragment @Inject constructor(
shareText(requireContext(), action.messageContent.body) shareText(requireContext(), action.messageContent.body)
} else if (action.messageContent is MessageWithAttachmentContent) { } else if (action.messageContent is MessageWithAttachmentContent) {
lifecycleScope.launch { lifecycleScope.launch {
val data = session.fileService().downloadFile(messageContent = action.messageContent) val result = runCatching { session.fileService().downloadFile(messageContent = action.messageContent) }
if (isAdded) { if (!isAdded) return@launch
shareMedia(requireContext(), data, getMimeTypeFromUri(requireContext(), data.toUri())) result.fold(
} { shareMedia(requireContext(), it, getMimeTypeFromUri(requireContext(), it.toUri())) },
{ showErrorInSnackbar(it) }
)
} }
} }
} }
@ -1701,16 +1703,22 @@ class RoomDetailFragment @Inject constructor(
return return
} }
lifecycleScope.launch { lifecycleScope.launch {
val data = session.fileService().downloadFile(messageContent = action.messageContent) val result = runCatching { session.fileService().downloadFile(messageContent = action.messageContent) }
if (isAdded) { if (!isAdded) return@launch
result.fold(
{
saveMedia( saveMedia(
context = requireContext(), context = requireContext(),
file = data, file = it,
title = action.messageContent.body, title = action.messageContent.body,
mediaMimeType = action.messageContent.mimeType ?: getMimeTypeFromUri(requireContext(), data.toUri()), mediaMimeType = action.messageContent.mimeType ?: getMimeTypeFromUri(requireContext(), it.toUri()),
notificationUtils = notificationUtils notificationUtils = notificationUtils
) )
},
{
showErrorInSnackbar(it)
} }
)
} }
} }

View File

@ -127,25 +127,27 @@ class RoomUploadsViewModel @AssistedInject constructor(
private fun handleShare(action: RoomUploadsAction.Share) { private fun handleShare(action: RoomUploadsAction.Share) {
viewModelScope.launch { viewModelScope.launch {
try { val event = try {
val file = session.fileService().downloadFile( val file = session.fileService().downloadFile(
messageContent = action.uploadEvent.contentWithAttachmentContent) messageContent = action.uploadEvent.contentWithAttachmentContent)
_viewEvents.post(RoomUploadsViewEvents.FileReadyForSharing(file)) RoomUploadsViewEvents.FileReadyForSharing(file)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(RoomUploadsViewEvents.Failure(failure)) RoomUploadsViewEvents.Failure(failure)
} }
_viewEvents.post(event)
} }
} }
private fun handleDownload(action: RoomUploadsAction.Download) { private fun handleDownload(action: RoomUploadsAction.Download) {
viewModelScope.launch { viewModelScope.launch {
try { val event = try {
val file = session.fileService().downloadFile( val file = session.fileService().downloadFile(
messageContent = action.uploadEvent.contentWithAttachmentContent) messageContent = action.uploadEvent.contentWithAttachmentContent)
_viewEvents.post(RoomUploadsViewEvents.FileReadyForSaving(file, action.uploadEvent.contentWithAttachmentContent.body)) RoomUploadsViewEvents.FileReadyForSaving(file, action.uploadEvent.contentWithAttachmentContent.body)
} catch (failure: Throwable) { } catch (failure: Throwable) {
_viewEvents.post(RoomUploadsViewEvents.Failure(failure)) RoomUploadsViewEvents.Failure(failure)
} }
_viewEvents.post(event)
} }
} }
} }

View File

@ -20,6 +20,7 @@ import androidx.preference.Preference
import im.vector.app.BuildConfig import im.vector.app.BuildConfig
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.preference.VectorPreference import im.vector.app.core.preference.VectorPreference
import im.vector.app.core.utils.FirstThrottler
import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.displayInWebView import im.vector.app.core.utils.displayInWebView
import im.vector.app.core.utils.openAppSettingsPage import im.vector.app.core.utils.openAppSettingsPage
@ -36,6 +37,8 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
override var titleRes = R.string.preference_root_help_about override var titleRes = R.string.preference_root_help_about
override val preferenceXmlRes = R.xml.vector_settings_help_about override val preferenceXmlRes = R.xml.vector_settings_help_about
private val firstThrottler = FirstThrottler(1000)
override fun bindPref() { override fun bindPref() {
// preference to start the App info screen, to facilitate App permissions access // preference to start the App info screen, to facilitate App permissions access
findPreference<VectorPreference>(APP_INFO_LINK_PREFERENCE_KEY)!! findPreference<VectorPreference>(APP_INFO_LINK_PREFERENCE_KEY)!!
@ -98,7 +101,9 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
// third party notice // third party notice
findPreference<VectorPreference>(VectorPreferences.SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY)!! findPreference<VectorPreference>(VectorPreferences.SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY)!!
.onPreferenceClickListener = Preference.OnPreferenceClickListener { .onPreferenceClickListener = Preference.OnPreferenceClickListener {
if (firstThrottler.canHandle()) {
activity?.displayInWebView(VectorSettingsUrls.THIRD_PARTY_LICENSES) activity?.displayInWebView(VectorSettingsUrls.THIRD_PARTY_LICENSES)
}
false false
} }