Merge pull request #1176 from vector-im/feature/target-sdk-29
Increase targetSdk to 29
This commit is contained in:
commit
c57fa3f0d0
|
@ -23,10 +23,10 @@ android:
|
|||
- platform-tools
|
||||
|
||||
# The BuildTools version used by your project
|
||||
- build-tools-28.0.3
|
||||
- build-tools-29.0.3
|
||||
|
||||
# The SDK version used to compile your project
|
||||
- android-28
|
||||
- android-29
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
|
|
|
@ -9,6 +9,7 @@ Features ✨:
|
|||
|
||||
Improvements 🙌:
|
||||
- Verification DM / Handle concurrent .start after .ready (#794)
|
||||
- Reimplementation of multiple attachment picker
|
||||
- Cross-Signing | Update Shield Logic for DM (#963)
|
||||
- Cross-Signing | Complete security new session design update (#1135)
|
||||
- Cross-Signing | Setup key backup as part of SSSS bootstrapping (#1201)
|
||||
|
@ -30,10 +31,10 @@ Translations 🗣:
|
|||
-
|
||||
|
||||
SDK API changes ⚠️:
|
||||
-
|
||||
- Increase targetSdkVersion to 29
|
||||
|
||||
Build 🧱:
|
||||
-
|
||||
- Compile with Android SDK 29 (Android Q)
|
||||
|
||||
Other changes:
|
||||
- Increase File Logger capacities ( + use dev log preferences)
|
||||
|
|
|
@ -3,11 +3,11 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 29
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@ androidExtensions {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 29
|
||||
testOptions.unitTests.includeAndroidResources = true
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "0.0.1"
|
||||
// Multidex is useful for tests
|
||||
|
|
|
@ -29,3 +29,7 @@ annotation class SessionCacheDirectory
|
|||
@Qualifier
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class CacheDirectory
|
||||
|
||||
@Qualifier
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class ExternalFilesDirectory
|
||||
|
|
|
@ -56,6 +56,9 @@ internal interface MatrixComponent {
|
|||
@CacheDirectory
|
||||
fun cacheDir(): File
|
||||
|
||||
@ExternalFilesDirectory
|
||||
fun externalFilesDir(): File?
|
||||
|
||||
fun olmManager(): OlmManager
|
||||
|
||||
fun taskExecutor(): TaskExecutor
|
||||
|
|
|
@ -57,6 +57,13 @@ internal object MatrixModule {
|
|||
return context.cacheDir
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@ExternalFilesDirectory
|
||||
fun providesExternalFilesDir(context: Context): File? {
|
||||
return context.getExternalFilesDir(null)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@MatrixScope
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This BroadcastReceiver is used only if the build code is below 24.
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package im.vector.matrix.android.internal.network
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.matrix.android.internal.session
|
||||
|
||||
import android.os.Environment
|
||||
import arrow.core.Try
|
||||
import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
||||
|
@ -25,6 +24,7 @@ import im.vector.matrix.android.api.util.Cancelable
|
|||
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
|
||||
import im.vector.matrix.android.internal.crypto.attachments.MXEncryptedAttachments
|
||||
import im.vector.matrix.android.internal.di.CacheDirectory
|
||||
import im.vector.matrix.android.internal.di.ExternalFilesDirectory
|
||||
import im.vector.matrix.android.internal.di.SessionCacheDirectory
|
||||
import im.vector.matrix.android.internal.di.Unauthenticated
|
||||
import im.vector.matrix.android.internal.extensions.foldToCallback
|
||||
|
@ -44,6 +44,8 @@ import javax.inject.Inject
|
|||
internal class DefaultFileService @Inject constructor(
|
||||
@CacheDirectory
|
||||
private val cacheDirectory: File,
|
||||
@ExternalFilesDirectory
|
||||
private val externalFilesDirectory: File?,
|
||||
@SessionCacheDirectory
|
||||
private val sessionCacheDirectory: File,
|
||||
private val contentUrlResolver: ContentUrlResolver,
|
||||
|
@ -103,7 +105,7 @@ internal class DefaultFileService @Inject constructor(
|
|||
private fun copyFile(file: File, downloadMode: FileService.DownloadMode): File {
|
||||
return when (downloadMode) {
|
||||
FileService.DownloadMode.TO_EXPORT ->
|
||||
file.copyTo(File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), file.name), true)
|
||||
file.copyTo(File(externalFilesDirectory, file.name), true)
|
||||
FileService.DownloadMode.FOR_EXTERNAL_SHARE ->
|
||||
file.copyTo(File(File(cacheDirectory, "ext_share"), file.name), true)
|
||||
FileService.DownloadMode.FOR_INTERNAL_USE ->
|
||||
|
|
|
@ -23,11 +23,9 @@ internal class Debouncer(private val handler: Handler) {
|
|||
private val runnables = HashMap<String, Runnable>()
|
||||
|
||||
fun debounce(identifier: String, r: Runnable, millis: Long): Boolean {
|
||||
if (runnables.containsKey(identifier)) {
|
||||
// debounce
|
||||
val old = runnables[identifier]
|
||||
handler.removeCallbacks(old)
|
||||
}
|
||||
// debounce
|
||||
runnables[identifier]?.let { runnable -> handler.removeCallbacks(runnable) }
|
||||
|
||||
insertRunnable(identifier, r, millis)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ PARAM_KEYSTORE_PATH=$1
|
|||
PARAM_APK=$2
|
||||
|
||||
# Other params
|
||||
BUILD_TOOLS_VERSION="28.0.3"
|
||||
BUILD_TOOLS_VERSION="29.0.3"
|
||||
MIN_SDK_VERSION=19
|
||||
|
||||
echo "Signing APK with build-tools version ${BUILD_TOOLS_VERSION} for min SDK version ${MIN_SDK_VERSION}..."
|
||||
|
|
|
@ -104,13 +104,13 @@ ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].
|
|||
def buildNumber = System.env.BUILDKITE_BUILD_NUMBER as Integer ?: 0
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
applicationId "im.vector.riotx"
|
||||
// Set to API 19 because motionLayout is min API 18.
|
||||
// In the future we may consider using an alternative of MotionLayout to support API 16. But for security reason, maybe not.
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
multiDexEnabled true
|
||||
|
||||
// `develop` branch will have version code from timestamp, to ensure each build from CI has a incremented versionCode.
|
||||
|
|
|
@ -21,7 +21,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.core.content.edit
|
||||
import im.vector.riotx.core.utils.lsFiles
|
||||
import timber.log.Timber
|
||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.riotx.push.fcm
|
|||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import android.widget.Toast
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
|
|
|
@ -171,7 +171,7 @@ class VectorApplication : Application(), HasVectorInjector, MatrixConfiguration.
|
|||
MultiDex.install(this)
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration?) {
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
vectorConfiguration.onConfigurationChanged()
|
||||
}
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
package im.vector.riotx.core.files
|
||||
|
||||
import android.app.DownloadManager
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.provider.MediaStore
|
||||
import androidx.annotation.WorkerThread
|
||||
import arrow.core.Try
|
||||
import okio.buffer
|
||||
|
@ -54,10 +57,24 @@ fun addEntryToDownloadManager(context: Context,
|
|||
mimeType: String,
|
||||
title: String = file.name,
|
||||
description: String = file.name) {
|
||||
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
|
||||
|
||||
try {
|
||||
downloadManager?.addCompletedDownload(title, description, true, mimeType, file.absolutePath, file.length(), true)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val contentValues = ContentValues().apply {
|
||||
put(MediaStore.Downloads.TITLE, title)
|
||||
put(MediaStore.Downloads.DISPLAY_NAME, description)
|
||||
put(MediaStore.Downloads.MIME_TYPE, mimeType)
|
||||
put(MediaStore.Downloads.SIZE, file.length())
|
||||
}
|
||||
context.contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)?.let { uri ->
|
||||
context.contentResolver.openOutputStream(uri)?.use { outputStream ->
|
||||
outputStream.sink().buffer().write(file.inputStream().use { it.readBytes() })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
|
||||
@Suppress("DEPRECATION")
|
||||
downloadManager?.addCompletedDownload(title, description, true, mimeType, file.absolutePath, file.length(), true)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## addEntryToDownloadManager(): Exception")
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ class VectorGlideDataFetcher(private val activeSessionHolder: ActiveSessionHolde
|
|||
|
||||
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
|
||||
Timber.v("Load data: $data")
|
||||
if (data.isLocalFile()) {
|
||||
if (data.isLocalFile() && data.url != null) {
|
||||
val initialFile = File(data.url)
|
||||
callback.onDataReady(FileInputStream(initialFile))
|
||||
return
|
||||
|
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.core.images
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class ImageTools @Inject constructor(private val context: Context) {
|
||||
|
||||
/**
|
||||
* Gets the [ExifInterface] value for the orientation for this local bitmap Uri.
|
||||
*
|
||||
* @param uri The URI to find the orientation for. Must be local.
|
||||
* @return The orientation value, which may be [ExifInterface.ORIENTATION_UNDEFINED].
|
||||
*/
|
||||
fun getOrientationForBitmap(uri: Uri): Int {
|
||||
var orientation = ExifInterface.ORIENTATION_UNDEFINED
|
||||
|
||||
if (uri.scheme == "content") {
|
||||
val proj = arrayOf(MediaStore.Images.Media.DATA)
|
||||
try {
|
||||
val cursor = context.contentResolver.query(uri, proj, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val idxData = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
|
||||
val path = it.getString(idxData)
|
||||
if (path.isNullOrBlank()) {
|
||||
Timber.w("Cannot find path in media db for uri $uri")
|
||||
return orientation
|
||||
}
|
||||
val exif = ExifInterface(path)
|
||||
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// eg SecurityException from com.google.android.apps.photos.content.GooglePhotosImageProvider URIs
|
||||
// eg IOException from trying to parse the returned path as a file when it is an http uri.
|
||||
Timber.e(e, "Cannot get orientation for bitmap")
|
||||
}
|
||||
} else if (uri.scheme == "file") {
|
||||
try {
|
||||
val path = uri.path
|
||||
if (path != null) {
|
||||
val exif = ExifInterface(path)
|
||||
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Cannot get EXIF for file uri $uri")
|
||||
}
|
||||
}
|
||||
|
||||
return orientation
|
||||
}
|
||||
}
|
|
@ -333,7 +333,7 @@ class EllipsizingTextView @JvmOverloads constructor(context: Context, attrs: Att
|
|||
* @param workingText text to strip end punctuation from
|
||||
* @return Text without end punctuation.
|
||||
*/
|
||||
fun stripEndPunctuation(workingText: CharSequence?): String {
|
||||
fun stripEndPunctuation(workingText: CharSequence): String {
|
||||
return mEndPunctPattern!!.matcher(workingText).replaceFirst("")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
restorables.forEach { it.onSaveInstanceState(outState) }
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
||||
restorables.forEach { it.onRestoreInstanceState(savedInstanceState) }
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
}
|
||||
|
|
|
@ -128,13 +128,13 @@ class CallService : VectorService() {
|
|||
* Display a call in progress notification.
|
||||
*/
|
||||
private fun displayCallInProgressNotification(intent: Intent) {
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID)
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
|
||||
|
||||
val notification = notificationUtils.buildPendingCallNotification(
|
||||
intent.getBooleanExtra(EXTRA_IS_VIDEO, false),
|
||||
intent.getStringExtra(EXTRA_ROOM_NAME),
|
||||
intent.getStringExtra(EXTRA_ROOM_ID),
|
||||
intent.getStringExtra(EXTRA_MATRIX_ID),
|
||||
intent.getStringExtra(EXTRA_ROOM_NAME) ?: "",
|
||||
intent.getStringExtra(EXTRA_ROOM_ID) ?: "",
|
||||
intent.getStringExtra(EXTRA_MATRIX_ID) ?: "",
|
||||
callId)
|
||||
|
||||
startForeground(NOTIFICATION_ID, notification)
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package im.vector.riotx.core.ui.views
|
||||
|
||||
import android.content.Context
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
|
|
@ -37,9 +37,10 @@ class Debouncer(private val handler: Handler) {
|
|||
|
||||
fun cancel(identifier: String) {
|
||||
if (runnables.containsKey(identifier)) {
|
||||
val old = runnables[identifier]
|
||||
handler.removeCallbacks(old)
|
||||
runnables.remove(identifier)
|
||||
runnables[identifier]?.let {
|
||||
handler.removeCallbacks(it)
|
||||
runnables.remove(identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ private fun logAction(file: File): Boolean {
|
|||
*/
|
||||
private fun recursiveActionOnFile(file: File, action: ActionOnFile): Boolean {
|
||||
if (file.isDirectory) {
|
||||
file.list().forEach {
|
||||
file.list()?.forEach {
|
||||
val result = recursiveActionOnFile(File(file, it), action)
|
||||
|
||||
if (!result) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.content.Context
|
|||
import android.media.Ringtone
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.core.content.edit
|
||||
import im.vector.riotx.features.settings.VectorPreferences
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ fun requestDisablingBatteryOptimization(activity: Activity, fragment: Fragment?,
|
|||
*/
|
||||
fun copyToClipboard(context: Context, text: CharSequence, showToast: Boolean = true, @StringRes toastMessage: Int = R.string.copied_to_clipboard) {
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
clipboard.primaryClip = ClipData.newPlainText("", text)
|
||||
clipboard.setPrimaryClip(ClipData.newPlainText("", text))
|
||||
if (showToast) {
|
||||
context.toast(toastMessage)
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@ object TextUtils {
|
|||
if (value < 1000) return value.toString() // deal with easy case
|
||||
|
||||
val e = suffixes.floorEntry(value)
|
||||
val divideBy = e.key
|
||||
val suffix = e.value
|
||||
val divideBy = e?.key
|
||||
val suffix = e?.value
|
||||
|
||||
val truncated = value / (divideBy!! / 10) // the number part of the output times 10
|
||||
val hasDecimal = truncated < 100 && truncated / 10.0 != (truncated / 10).toDouble()
|
||||
|
|
|
@ -43,7 +43,7 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
}
|
||||
|
||||
fun getOutput(intent: Intent): List<ContentAttachmentData> {
|
||||
return intent.getParcelableArrayListExtra(ATTACHMENTS_PREVIEW_RESULT)
|
||||
return intent.getParcelableArrayListExtra(ATTACHMENTS_PREVIEW_RESULT) ?: emptyList()
|
||||
}
|
||||
|
||||
fun getKeepOriginalSize(intent: Intent): Boolean {
|
||||
|
|
|
@ -40,7 +40,7 @@ class KeysExporter(private val session: Session) {
|
|||
runCatching {
|
||||
val data = awaitCallback<ByteArray> { session.cryptoService().exportRoomKeys(password, it) }
|
||||
withContext(Dispatchers.IO) {
|
||||
val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
val parentDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
|
||||
val file = File(parentDir, "riotx-keys-" + System.currentTimeMillis() + ".txt")
|
||||
|
||||
writeToFile(data, file)
|
||||
|
|
|
@ -95,7 +95,7 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor(): VectorBaseF
|
|||
|
||||
// used just to have default link representation
|
||||
val clickableSpan = object : ClickableSpan() {
|
||||
override fun onClick(widget: View?) {}
|
||||
override fun onClick(widget: View) {}
|
||||
}
|
||||
val start = helperText.indexOf(clickableText)
|
||||
val end = start + clickableText.length
|
||||
|
|
|
@ -153,7 +153,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
|||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
toast(failure.localizedMessage)
|
||||
toast(failure.localizedMessage ?: getString(R.string.unexpected_error))
|
||||
hideWaitingView()
|
||||
}
|
||||
})
|
||||
|
|
|
@ -167,7 +167,7 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment()
|
|||
GlobalScope.launch(Dispatchers.Main) {
|
||||
Try {
|
||||
withContext(Dispatchers.IO) {
|
||||
val parentDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
val parentDir = context?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
|
||||
val file = File(parentDir, "recovery-key-" + System.currentTimeMillis() + ".txt")
|
||||
|
||||
writeToFile(data, file)
|
||||
|
|
|
@ -163,8 +163,8 @@ class SharedSecureStorageViewModel @AssistedInject constructor(
|
|||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: SharedSecureStorageViewState): SharedSecureStorageViewModel? {
|
||||
val activity: SharedSecureStorageActivity = viewModelContext.activity()
|
||||
val args: SharedSecureStorageActivity.Args = activity.intent.getParcelableExtra(MvRx.KEY_ARG)
|
||||
return activity.viewModelFactory.create(state, args)
|
||||
val args: SharedSecureStorageActivity.Args? = activity.intent.getParcelableExtra(MvRx.KEY_ARG)
|
||||
return args?.let { activity.viewModelFactory.create(state, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -384,7 +384,8 @@ class VerificationBottomSheetViewModel @AssistedInject constructor(
|
|||
Unit
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
_viewEvents.post(VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage))
|
||||
_viewEvents.post(
|
||||
VerificationBottomSheetViewEvents.ModalError(failure.localizedMessage ?: stringProvider.getString(R.string.unexpected_error)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package im.vector.riotx.features.disclaimer
|
||||
|
||||
import android.app.Activity
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
|
|
@ -782,7 +782,7 @@ class RoomDetailFragment @Inject constructor(
|
|||
updateComposerText("")
|
||||
}
|
||||
is RoomDetailViewEvents.SlashCommandResultError -> {
|
||||
displayCommandError(sendMessageResult.throwable.localizedMessage)
|
||||
displayCommandError(sendMessageResult.throwable.localizedMessage ?: getString(R.string.unexpected_error))
|
||||
}
|
||||
is RoomDetailViewEvents.SlashCommandNotImplemented -> {
|
||||
displayCommandError(getString(R.string.not_implemented))
|
||||
|
|
|
@ -440,11 +440,11 @@ class MessageItemFactory @Inject constructor(
|
|||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
|
||||
spannable.setSpan(object : ClickableSpan() {
|
||||
override fun onClick(widget: View?) {
|
||||
override fun onClick(widget: View) {
|
||||
callback?.onEditedDecorationClicked(informationData)
|
||||
}
|
||||
|
||||
override fun updateDrawState(ds: TextPaint?) {
|
||||
override fun updateDrawState(ds: TextPaint) {
|
||||
// nop
|
||||
}
|
||||
},
|
||||
|
|
|
@ -56,10 +56,17 @@ class ImageMediaViewerActivity : VectorBaseActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(im.vector.riotx.R.layout.activity_image_media_viewer)
|
||||
mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA)
|
||||
|
||||
if (intent.hasExtra(EXTRA_MEDIA_DATA)) {
|
||||
mediaData = intent.getParcelableExtra(EXTRA_MEDIA_DATA)!!
|
||||
} else {
|
||||
finish()
|
||||
}
|
||||
|
||||
intent.extras?.getString(EXTRA_SHARED_TRANSITION_NAME)?.let {
|
||||
ViewCompat.setTransitionName(imageTransitionView, it)
|
||||
}
|
||||
|
||||
if (mediaData.url.isNullOrEmpty()) {
|
||||
supportFinishAfterTransition()
|
||||
return
|
||||
|
|
|
@ -37,11 +37,14 @@ class VideoMediaViewerActivity : VectorBaseActivity() {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(im.vector.riotx.R.layout.activity_video_media_viewer)
|
||||
val mediaData = intent.getParcelableExtra<VideoContentRenderer.Data>(EXTRA_MEDIA_DATA)
|
||||
|
||||
configureToolbar(videoMediaViewerToolbar, mediaData)
|
||||
imageContentRenderer.render(mediaData.thumbnailMediaData, ImageContentRenderer.Mode.FULL_SIZE, videoMediaViewerThumbnailView)
|
||||
videoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerLoading, videoMediaViewerVideoView, videoMediaViewerErrorView)
|
||||
if (intent.hasExtra(EXTRA_MEDIA_DATA)) {
|
||||
val mediaData = intent.getParcelableExtra<VideoContentRenderer.Data>(EXTRA_MEDIA_DATA)!!
|
||||
|
||||
configureToolbar(videoMediaViewerToolbar, mediaData)
|
||||
imageContentRenderer.render(mediaData.thumbnailMediaData, ImageContentRenderer.Mode.FULL_SIZE, videoMediaViewerThumbnailView)
|
||||
videoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerLoading, videoMediaViewerVideoView, videoMediaViewerErrorView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureToolbar(toolbar: Toolbar, mediaData: VideoContentRenderer.Data) {
|
||||
|
|
|
@ -97,7 +97,7 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
|||
val message = getReplyMessage(intent)
|
||||
val roomId = intent.getStringExtra(KEY_ROOM_ID)
|
||||
|
||||
if (message.isNullOrBlank() || roomId.isBlank()) {
|
||||
if (message.isNullOrBlank() || roomId.isNullOrBlank()) {
|
||||
// ignore this event
|
||||
// Can this happen? should we update notification?
|
||||
return
|
||||
|
|
|
@ -77,7 +77,7 @@ class VectorFileLogger @Inject constructor(val context: Context, private val vec
|
|||
sFileHandler?.formatter = LogFormatter()
|
||||
sLogger.useParentHandlers = false
|
||||
sLogger.level = Level.ALL
|
||||
sLogger.addHandler(sFileHandler)
|
||||
sFileHandler?.let { sLogger.addHandler(it) }
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "Failed to initialize FileLogger")
|
||||
|
|
|
@ -70,7 +70,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
if (isFirstCreation()) {
|
||||
val args = intent.getParcelableExtra<RoomPreviewData>(ARG)
|
||||
|
||||
if (args.worldReadable) {
|
||||
if (args?.worldReadable == true) {
|
||||
// TODO Room preview: Note: M does not recommend to use /events anymore, so for now we just display the room preview
|
||||
// TODO the same way if it was not world readable
|
||||
addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
|
||||
|
|
|
@ -19,7 +19,7 @@ package im.vector.riotx.features.settings
|
|||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import android.preference.PreferenceManager
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.core.content.edit
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.R
|
||||
|
@ -59,9 +59,9 @@ object VectorLocale {
|
|||
val preferences = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
|
||||
if (preferences.contains(APPLICATION_LOCALE_LANGUAGE_KEY)) {
|
||||
applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, ""),
|
||||
preferences.getString(APPLICATION_LOCALE_COUNTRY_KEY, ""),
|
||||
preferences.getString(APPLICATION_LOCALE_VARIANT_KEY, "")
|
||||
applicationLocale = Locale(preferences.getString(APPLICATION_LOCALE_LANGUAGE_KEY, "")!!,
|
||||
preferences.getString(APPLICATION_LOCALE_COUNTRY_KEY, "")!!,
|
||||
preferences.getString(APPLICATION_LOCALE_VARIANT_KEY, "")!!
|
||||
)
|
||||
} else {
|
||||
applicationLocale = Locale.getDefault()
|
||||
|
|
|
@ -29,7 +29,6 @@ import im.vector.riotx.R
|
|||
import im.vector.riotx.features.homeserver.ServerUrlsRepository
|
||||
import im.vector.riotx.features.themes.ThemeUtils
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorPreferences @Inject constructor(private val context: Context) {
|
||||
|
@ -68,7 +67,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
const val SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_EXPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
|
||||
const val SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_IMPORT_E2E_ROOM_KEYS_PREFERENCE_KEY"
|
||||
const val SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY = "SETTINGS_ENCRYPTION_NEVER_SENT_TO_PREFERENCE_KEY"
|
||||
const val SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY = "SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY"
|
||||
const val SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY = "SETTINGS_SHOW_DEVICES_LIST_PREFERENCE_KEY"
|
||||
|
||||
const val SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY = "SETTINGS_SECURE_MESSAGE_RECOVERY_PREFERENCE_KEY"
|
||||
|
||||
|
@ -427,11 +426,11 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
val toneUri = getNotificationRingTone() ?: return null
|
||||
|
||||
try {
|
||||
val proj = arrayOf(MediaStore.Audio.Media.DATA)
|
||||
val proj = arrayOf(MediaStore.Audio.Media.DISPLAY_NAME)
|
||||
return context.contentResolver.query(toneUri, proj, null, null, null)?.use {
|
||||
val columnIndex = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
|
||||
val columnIndex = it.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)
|
||||
it.moveToFirst()
|
||||
File(it.getString(columnIndex)).nameWithoutExtension
|
||||
it.getString(columnIndex)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "## getNotificationRingToneName() failed")
|
||||
|
|
|
@ -332,7 +332,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onFailure(failure: Throwable) {
|
||||
appContext.toast(failure.localizedMessage)
|
||||
appContext.toast(failure.localizedMessage ?: getString(R.string.unexpected_error))
|
||||
hideLoadingView()
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue