Do not use deprecated Fragment.startActivityForResult anymore

This commit is contained in:
Benoit Marty 2020-10-07 16:02:01 +02:00
parent 05950ec1c8
commit ff0f42900d
38 changed files with 464 additions and 547 deletions

View File

@ -66,6 +66,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2' implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.recyclerview:recyclerview:1.1.0" implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'

View File

@ -36,6 +36,7 @@ android {
dependencies { dependencies {
implementation project(":matrix-sdk-android") implementation project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0' implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
// Paging // Paging

View File

@ -121,6 +121,7 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
implementation "androidx.appcompat:appcompat:1.2.0" implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.core:core-ktx:1.3.2" implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

View File

@ -41,9 +41,9 @@ android {
} }
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation 'androidx.exifinterface:exifinterface:1.3.0' implementation 'androidx.exifinterface:exifinterface:1.3.0'
// Log // Log

View File

@ -16,7 +16,6 @@
package im.vector.lib.multipicker package im.vector.lib.multipicker
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
@ -30,15 +29,9 @@ class AudioPicker(override val requestCode: Int) : Picker<MultiPickerAudioType>(
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* Returns selected audio files or empty list if request code is wrong * Returns selected audio files or empty list if user did not select any files.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
override fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<MultiPickerAudioType> { override fun getSelectedFiles(context: Context, data: Intent?): List<MultiPickerAudioType> {
if (requestCode != this.requestCode && resultCode != Activity.RESULT_OK) {
return emptyList()
}
val audioList = mutableListOf<MultiPickerAudioType>() val audioList = mutableListOf<MultiPickerAudioType>()
getSelectedUriList(data).forEach { selectedUri -> getSelectedUriList(data).forEach { selectedUri ->

View File

@ -21,8 +21,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.provider.MediaStore import android.provider.MediaStore
import androidx.activity.result.ActivityResultLauncher
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.fragment.app.Fragment
import im.vector.lib.multipicker.entity.MultiPickerImageType import im.vector.lib.multipicker.entity.MultiPickerImageType
import im.vector.lib.multipicker.utils.ImageUtils import im.vector.lib.multipicker.utils.ImageUtils
import java.io.File import java.io.File
@ -51,15 +51,14 @@ class CameraPicker(val requestCode: Int) {
/** /**
* Start camera by using a Fragment * Start camera by using a Fragment
* @param fragment Fragment to handle onActivityResult().
* @return Uri of taken photo or null if the operation is cancelled. * @return Uri of taken photo or null if the operation is cancelled.
*/ */
fun startWithExpectingFile(fragment: Fragment): Uri? { fun startWithExpectingFile(context: Context, activityResultLauncher: ActivityResultLauncher<Intent>): Uri? {
val photoUri = createPhotoUri(fragment.requireContext()) val photoUri = createPhotoUri(context)
val intent = createIntent().apply { val intent = createIntent().apply {
putExtra(MediaStore.EXTRA_OUTPUT, photoUri) putExtra(MediaStore.EXTRA_OUTPUT, photoUri)
} }
fragment.startActivityForResult(intent, requestCode) activityResultLauncher.launch(intent)
return photoUri return photoUri
} }
@ -69,8 +68,7 @@ class CameraPicker(val requestCode: Int) {
* or result code is not Activity.RESULT_OK * or result code is not Activity.RESULT_OK
* or user cancelled the operation. * or user cancelled the operation.
*/ */
fun getTakenPhoto(context: Context, requestCode: Int, resultCode: Int, photoUri: Uri): MultiPickerImageType? { fun getTakenPhoto(context: Context, photoUri: Uri): MultiPickerImageType? {
if (requestCode == this.requestCode && resultCode == Activity.RESULT_OK) {
val projection = arrayOf( val projection = arrayOf(
MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.SIZE MediaStore.Images.Media.SIZE
@ -104,7 +102,6 @@ class CameraPicker(val requestCode: Int) {
) )
} }
} }
}
return null return null
} }

View File

@ -16,7 +16,6 @@
package im.vector.lib.multipicker package im.vector.lib.multipicker
import android.app.Activity
import android.content.ContentResolver import android.content.ContentResolver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -30,15 +29,9 @@ class ContactPicker(override val requestCode: Int) : Picker<MultiPickerContactTy
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* Returns selected contact or empty list if request code is wrong * Returns selected contact or empty list if user did not select any contacts.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
override fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<MultiPickerContactType> { override fun getSelectedFiles(context: Context, data: Intent?): List<MultiPickerContactType> {
if (requestCode != this.requestCode && resultCode != Activity.RESULT_OK) {
return emptyList()
}
val contactList = mutableListOf<MultiPickerContactType>() val contactList = mutableListOf<MultiPickerContactType>()
data?.data?.let { selectedUri -> data?.data?.let { selectedUri ->

View File

@ -16,7 +16,6 @@
package im.vector.lib.multipicker package im.vector.lib.multipicker
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.provider.OpenableColumns import android.provider.OpenableColumns
@ -29,15 +28,9 @@ class FilePicker(override val requestCode: Int) : Picker<MultiPickerFileType>(re
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* Returns selected files or empty list if request code is wrong * Returns selected files or empty list if user did not select any files.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
override fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<MultiPickerFileType> { override fun getSelectedFiles(context: Context, data: Intent?): List<MultiPickerFileType> {
if (requestCode != this.requestCode && resultCode != Activity.RESULT_OK) {
return emptyList()
}
val fileList = mutableListOf<MultiPickerFileType>() val fileList = mutableListOf<MultiPickerFileType>()
getSelectedUriList(data).forEach { selectedUri -> getSelectedUriList(data).forEach { selectedUri ->

View File

@ -16,7 +16,6 @@
package im.vector.lib.multipicker package im.vector.lib.multipicker
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.provider.MediaStore import android.provider.MediaStore
@ -30,15 +29,9 @@ class ImagePicker(override val requestCode: Int) : Picker<MultiPickerImageType>(
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* Returns selected image files or empty list if request code is wrong * Returns selected image files or empty list if user did not select any files.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
override fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<MultiPickerImageType> { override fun getSelectedFiles(context: Context, data: Intent?): List<MultiPickerImageType> {
if (requestCode != this.requestCode && resultCode != Activity.RESULT_OK) {
return emptyList()
}
val imageList = mutableListOf<MultiPickerImageType>() val imageList = mutableListOf<MultiPickerImageType>()
getSelectedUriList(data).forEach { selectedUri -> getSelectedUriList(data).forEach { selectedUri ->

View File

@ -22,7 +22,7 @@ import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.ResolveInfo import android.content.pm.ResolveInfo
import android.net.Uri import android.net.Uri
import androidx.fragment.app.Fragment import androidx.activity.result.ActivityResultLauncher
/** /**
* Abstract class to provide all types of Pickers * Abstract class to provide all types of Pickers
@ -33,11 +33,9 @@ abstract class Picker<T>(open val requestCode: Int) {
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* @return selected files or empty list if request code is wrong * @return selected files or empty list if user did not select any files.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
abstract fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<T> abstract fun getSelectedFiles(context: Context, data: Intent?): List<T>
/** /**
* Use this function to retrieve files which are shared from another application or internally * Use this function to retrieve files which are shared from another application or internally
@ -61,7 +59,7 @@ abstract class Picker<T>(open val requestCode: Int) {
context.grantUriPermission(packageName, it, Intent.FLAG_GRANT_READ_URI_PERMISSION) context.grantUriPermission(packageName, it, Intent.FLAG_GRANT_READ_URI_PERMISSION)
} }
} }
return getSelectedFiles(context, requestCode, Activity.RESULT_OK, data) return getSelectedFiles(context, data)
} }
/** /**
@ -84,10 +82,10 @@ abstract class Picker<T>(open val requestCode: Int) {
/** /**
* Start Storage Access Framework UI by using a Fragment. * Start Storage Access Framework UI by using a Fragment.
* @param fragment Fragment to handle onActivityResult(). * @param activityResultLauncher to handle the result.
*/ */
fun startWith(fragment: Fragment) { fun startWith(activityResultLauncher: ActivityResultLauncher<Intent>) {
fragment.startActivityForResult(createIntent().apply { addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) }, requestCode) activityResultLauncher.launch(createIntent().apply { addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) })
} }
protected fun getSelectedUriList(data: Intent?): List<Uri> { protected fun getSelectedUriList(data: Intent?): List<Uri> {

View File

@ -16,7 +16,6 @@
package im.vector.lib.multipicker package im.vector.lib.multipicker
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.media.MediaMetadataRetriever import android.media.MediaMetadataRetriever
@ -30,15 +29,9 @@ class VideoPicker(override val requestCode: Int) : Picker<MultiPickerVideoType>(
/** /**
* Call this function from onActivityResult(int, int, Intent). * Call this function from onActivityResult(int, int, Intent).
* Returns selected video files or empty list if request code is wrong * Returns selected video files or empty list if user did not select any files.
* or result code is not Activity.RESULT_OK
* or user did not select any files.
*/ */
override fun getSelectedFiles(context: Context, requestCode: Int, resultCode: Int, data: Intent?): List<MultiPickerVideoType> { override fun getSelectedFiles(context: Context, data: Intent?): List<MultiPickerVideoType> {
if (requestCode != this.requestCode && resultCode != Activity.RESULT_OK) {
return emptyList()
}
val videoList = mutableListOf<MultiPickerVideoType>() val videoList = mutableListOf<MultiPickerVideoType>()
getSelectedUriList(data).forEach { selectedUri -> getSelectedUriList(data).forEach { selectedUri ->

View File

@ -17,7 +17,11 @@
package im.vector.app.core.extensions package im.vector.app.core.extensions
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.os.Parcelable import android.os.Parcelable
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
@ -26,6 +30,10 @@ import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.Locale import java.util.Locale
fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit): ActivityResultLauncher<Intent> {
return registerForActivityResult(ActivityResultContracts.StartActivityForResult(), onResult)
}
fun VectorBaseFragment.addFragment( fun VectorBaseFragment.addFragment(
frameId: Int, frameId: Int,
fragment: Fragment, fragment: Fragment,
@ -160,15 +168,15 @@ fun Fragment.getAllChildFragments(): List<Fragment> {
// Define a missing constant // Define a missing constant
const val POP_BACK_STACK_EXCLUSIVE = 0 const val POP_BACK_STACK_EXCLUSIVE = 0
fun Fragment.queryExportKeys(userId: String, requestCode: Int) { fun Fragment.queryExportKeys(userId: String, activityResultLauncher: ActivityResultLauncher<Intent>) {
val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date()) val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
selectTxtFileToWrite( selectTxtFileToWrite(
activity = requireActivity(), activity = requireActivity(),
fragment = this, activityResultLauncher = activityResultLauncher,
defaultFileName = "element-megolm-export-$userId-$timestamp.txt", defaultFileName = "element-megolm-export-$userId-$timestamp.txt",
chooserHint = getString(R.string.keys_backup_setup_step1_manual_export), chooserHint = getString(R.string.keys_backup_setup_step1_manual_export),
requestCode = requestCode requestCode = 0
) )
} }
@ -177,7 +185,7 @@ fun Activity.queryExportKeys(userId: String, requestCode: Int) {
selectTxtFileToWrite( selectTxtFileToWrite(
activity = this, activity = this,
fragment = null, activityResultLauncher = null,
defaultFileName = "element-megolm-export-$userId-$timestamp.txt", defaultFileName = "element-megolm-export-$userId-$timestamp.txt",
chooserHint = getString(R.string.keys_backup_setup_step1_manual_export), chooserHint = getString(R.string.keys_backup_setup_step1_manual_export),
requestCode = requestCode requestCode = requestCode

View File

@ -31,6 +31,7 @@ import android.provider.Browser
import android.provider.MediaStore import android.provider.MediaStore
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import android.widget.Toast import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsSession import androidx.browser.customtabs.CustomTabsSession
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@ -130,7 +131,7 @@ fun openSoundRecorder(activity: Activity, requestCode: Int) {
* Open file selection activity * Open file selection activity
*/ */
fun openFileSelection(activity: Activity, fun openFileSelection(activity: Activity,
fragment: Fragment?, activityResultLauncher: ActivityResultLauncher<Intent>?,
allowMultipleSelection: Boolean, allowMultipleSelection: Boolean,
requestCode: Int) { requestCode: Int) {
val fileIntent = Intent(Intent.ACTION_GET_CONTENT) val fileIntent = Intent(Intent.ACTION_GET_CONTENT)
@ -140,8 +141,8 @@ fun openFileSelection(activity: Activity,
fileIntent.type = "*/*" fileIntent.type = "*/*"
try { try {
fragment activityResultLauncher
?.startActivityForResult(fileIntent, requestCode) ?.launch(fileIntent)
?: run { ?: run {
activity.startActivityForResult(fileIntent, requestCode) activity.startActivityForResult(fileIntent, requestCode)
} }
@ -440,7 +441,7 @@ fun openPlayStore(activity: Activity, appId: String = BuildConfig.APPLICATION_ID
*/ */
fun selectTxtFileToWrite( fun selectTxtFileToWrite(
activity: Activity, activity: Activity,
fragment: Fragment?, activityResultLauncher: ActivityResultLauncher<Intent>?,
defaultFileName: String, defaultFileName: String,
chooserHint: String, chooserHint: String,
requestCode: Int requestCode: Int
@ -452,8 +453,8 @@ fun selectTxtFileToWrite(
try { try {
val chooserIntent = Intent.createChooser(intent, chooserHint) val chooserIntent = Intent.createChooser(intent, chooserHint)
if (fragment != null) { if (activityResultLauncher != null) {
fragment.startActivityForResult(chooserIntent, requestCode) activityResultLauncher.launch(chooserIntent)
} else { } else {
activity.startActivityForResult(chooserIntent, requestCode) activity.startActivityForResult(chooserIntent, requestCode)
} }

View File

@ -15,12 +15,11 @@
*/ */
package im.vector.app.features.attachments package im.vector.app.features.attachments
import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.activity.result.ActivityResultLauncher
import im.vector.app.core.platform.Restorable import im.vector.app.core.platform.Restorable
import im.vector.lib.multipicker.MultiPicker import im.vector.lib.multipicker.MultiPicker
import org.matrix.android.sdk.BuildConfig import org.matrix.android.sdk.BuildConfig
@ -48,6 +47,7 @@ class AttachmentsHelper(val context: Context, val callback: Callback) : Restorab
// Capture path allows to handle camera image picking. It must be restored if the activity gets killed. // Capture path allows to handle camera image picking. It must be restored if the activity gets killed.
private var captureUri: Uri? = null private var captureUri: Uri? = null
// The pending type is set if we have to handle permission request. It must be restored if the activity gets killed. // The pending type is set if we have to handle permission request. It must be restored if the activity gets killed.
var pendingType: AttachmentTypeSelectorView.Type? = null var pendingType: AttachmentTypeSelectorView.Type? = null
@ -72,80 +72,79 @@ class AttachmentsHelper(val context: Context, val callback: Callback) : Restorab
/** /**
* Starts the process for handling file picking * Starts the process for handling file picking
*/ */
fun selectFile(fragment: Fragment) { fun selectFile(activityResultLauncher: ActivityResultLauncher<Intent>) {
MultiPicker.get(MultiPicker.FILE).startWith(fragment) MultiPicker.get(MultiPicker.FILE).startWith(activityResultLauncher)
} }
/** /**
* Starts the process for handling image picking * Starts the process for handling image picking
*/ */
fun selectGallery(fragment: Fragment) { fun selectGallery(activityResultLauncher: ActivityResultLauncher<Intent>) {
MultiPicker.get(MultiPicker.IMAGE).startWith(fragment) MultiPicker.get(MultiPicker.IMAGE).startWith(activityResultLauncher)
} }
/** /**
* Starts the process for handling audio picking * Starts the process for handling audio picking
*/ */
fun selectAudio(fragment: Fragment) { fun selectAudio(activityResultLauncher: ActivityResultLauncher<Intent>) {
MultiPicker.get(MultiPicker.AUDIO).startWith(fragment) MultiPicker.get(MultiPicker.AUDIO).startWith(activityResultLauncher)
} }
/** /**
* Starts the process for handling capture image picking * Starts the process for handling capture image picking
*/ */
fun openCamera(fragment: Fragment) { fun openCamera(context: Context, activityResultLauncher: ActivityResultLauncher<Intent>) {
captureUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(fragment) captureUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(context, activityResultLauncher)
} }
/** /**
* Starts the process for handling contact picking * Starts the process for handling contact picking
*/ */
fun selectContact(fragment: Fragment) { fun selectContact(activityResultLauncher: ActivityResultLauncher<Intent>) {
MultiPicker.get(MultiPicker.CONTACT).startWith(fragment) MultiPicker.get(MultiPicker.CONTACT).startWith(activityResultLauncher)
} }
/** /**
* This methods aims to handle on activity result data. * This methods aims to handle the result data.
*
* @return true if it can handle the data, false otherwise
*/ */
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { fun onFileResult(data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
MultiPicker.REQUEST_CODE_PICK_FILE -> {
callback.onContentAttachmentsReady( callback.onContentAttachmentsReady(
MultiPicker.get(MultiPicker.FILE) MultiPicker.get(MultiPicker.FILE)
.getSelectedFiles(context, requestCode, resultCode, data) .getSelectedFiles(context, data)
.map { it.toContentAttachmentData() } .map { it.toContentAttachmentData() }
) )
} }
MultiPicker.REQUEST_CODE_PICK_AUDIO -> {
fun onAudioResult(data: Intent?) {
callback.onContentAttachmentsReady( callback.onContentAttachmentsReady(
MultiPicker.get(MultiPicker.AUDIO) MultiPicker.get(MultiPicker.AUDIO)
.getSelectedFiles(context, requestCode, resultCode, data) .getSelectedFiles(context, data)
.map { it.toContentAttachmentData() } .map { it.toContentAttachmentData() }
) )
} }
MultiPicker.REQUEST_CODE_PICK_CONTACT -> {
fun onContactResult(data: Intent?) {
MultiPicker.get(MultiPicker.CONTACT) MultiPicker.get(MultiPicker.CONTACT)
.getSelectedFiles(context, requestCode, resultCode, data) .getSelectedFiles(context, data)
.firstOrNull() .firstOrNull()
?.toContactAttachment() ?.toContactAttachment()
?.let { ?.let {
callback.onContactAttachmentReady(it) callback.onContactAttachmentReady(it)
} }
} }
MultiPicker.REQUEST_CODE_PICK_IMAGE -> {
fun onImageResult(data: Intent?) {
callback.onContentAttachmentsReady( callback.onContentAttachmentsReady(
MultiPicker.get(MultiPicker.IMAGE) MultiPicker.get(MultiPicker.IMAGE)
.getSelectedFiles(context, requestCode, resultCode, data) .getSelectedFiles(context, data)
.map { it.toContentAttachmentData() } .map { it.toContentAttachmentData() }
) )
} }
MultiPicker.REQUEST_CODE_TAKE_PHOTO -> {
fun onPhotoResult() {
captureUri?.let { captureUri -> captureUri?.let { captureUri ->
MultiPicker.get(MultiPicker.CAMERA) MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(context, requestCode, resultCode, captureUri) .getTakenPhoto(context, captureUri)
?.let { ?.let {
callback.onContentAttachmentsReady( callback.onContentAttachmentsReady(
listOf(it).map { it.toContentAttachmentData() } listOf(it).map { it.toContentAttachmentData() }
@ -153,19 +152,14 @@ class AttachmentsHelper(val context: Context, val callback: Callback) : Restorab
} }
} }
} }
MultiPicker.REQUEST_CODE_PICK_VIDEO -> {
fun onVideoResult(data: Intent?) {
callback.onContentAttachmentsReady( callback.onContentAttachmentsReady(
MultiPicker.get(MultiPicker.VIDEO) MultiPicker.get(MultiPicker.VIDEO)
.getSelectedFiles(context, requestCode, resultCode, data) .getSelectedFiles(context, data)
.map { it.toContentAttachmentData() } .map { it.toContentAttachmentData() }
) )
} }
else -> return false
}
return true
}
return false
}
/** /**
* This methods aims to handle share intent. * This methods aims to handle share intent.

View File

@ -30,8 +30,6 @@ import org.matrix.android.sdk.api.session.content.ContentAttachmentData
class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
companion object { companion object {
const val REQUEST_CODE = 55
private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS" private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS"
private const val ATTACHMENTS_PREVIEW_RESULT = "ATTACHMENTS_PREVIEW_RESULT" private const val ATTACHMENTS_PREVIEW_RESULT = "ATTACHMENTS_PREVIEW_RESULT"
private const val KEEP_ORIGINAL_IMAGES_SIZE = "KEEP_ORIGINAL_IMAGES_SIZE" private const val KEEP_ORIGINAL_IMAGES_SIZE = "KEEP_ORIGINAL_IMAGES_SIZE"

View File

@ -298,6 +298,7 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == CAPTURE_PERMISSION_REQUEST_CODE && allGranted(grantResults)) { if (requestCode == CAPTURE_PERMISSION_REQUEST_CODE && allGranted(grantResults)) {
start() start()
} else { } else {

View File

@ -150,6 +150,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, Ji
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults) JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults)
} }

View File

@ -111,6 +111,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (allGranted(grantResults)) { if (allGranted(grantResults)) {
if (requestCode == PERMISSION_REQUEST_CODE_READ_CONTACTS) { if (requestCode == PERMISSION_REQUEST_CODE_READ_CONTACTS) {
doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) } doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) }

View File

@ -31,6 +31,7 @@ import butterknife.BindView
import butterknife.OnClick import butterknife.OnClick
import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialog
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.LiveEvent import im.vector.app.core.utils.LiveEvent
import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.copyToClipboard
@ -48,10 +49,6 @@ import javax.inject.Inject
class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() { class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() {
companion object {
private const val SAVE_RECOVERY_KEY_REQUEST_CODE = 2754
}
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step3 override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step3
@BindView(R.id.keys_backup_setup_step3_button) @BindView(R.id.keys_backup_setup_step3_button)
@ -138,10 +135,10 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment()
val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date()) val timestamp = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
selectTxtFileToWrite( selectTxtFileToWrite(
activity = requireActivity(), activity = requireActivity(),
fragment = this, activityResultLauncher = saveRecoveryActivityResultLauncher,
defaultFileName = "recovery-key-$userId-$timestamp.txt", defaultFileName = "recovery-key-$userId-$timestamp.txt",
chooserHint = getString(R.string.save_recovery_key_chooser_hint), chooserHint = getString(R.string.save_recovery_key_chooser_hint),
requestCode = SAVE_RECOVERY_KEY_REQUEST_CODE requestCode = 0
) )
dialog.dismiss() dialog.dismiss()
} }
@ -202,16 +199,12 @@ class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment()
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val saveRecoveryActivityResultLauncher = registerStartForActivityResult { activityRessult ->
when (requestCode) { val uri = activityRessult.data?.data ?: return@registerStartForActivityResult
SAVE_RECOVERY_KEY_REQUEST_CODE -> { if (activityRessult.resultCode == Activity.RESULT_OK) {
val uri = data?.data
if (resultCode == Activity.RESULT_OK && uri != null) {
viewModel.recoveryKey.value?.let { viewModel.recoveryKey.value?.let {
exportRecoveryKeyToFile(uri, it) exportRecoveryKeyToFile(uri, it)
} }
} }
} }
} }
}
}

View File

@ -16,7 +16,6 @@
package im.vector.app.features.crypto.verification.choose package im.vector.app.features.crypto.verification.choose
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
@ -25,6 +24,7 @@ import com.airbnb.mvrx.withState
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.checkPermissions
@ -91,17 +91,13 @@ class VerificationChooseMethodFragment @Inject constructor(
} }
private fun doOpenQRCodeScanner() { private fun doOpenQRCodeScanner() {
QrCodeScannerActivity.startForResult(this) QrCodeScannerActivity.startForResult(requireActivity(), scanActivityResultLauncher)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val scanActivityResultLauncher = registerStartForActivityResult { activityResult ->
super.onActivityResult(requestCode, resultCode, data) if (activityResult.resultCode == Activity.RESULT_OK) {
val scannedQrCode = QrCodeScannerActivity.getResultText(activityResult.data)
if (resultCode == Activity.RESULT_OK) { val wasQrCode = QrCodeScannerActivity.getResultIsQrCode(activityResult.data)
when (requestCode) {
QrCodeScannerActivity.QR_CODE_SCANNER_REQUEST_CODE -> {
val scannedQrCode = QrCodeScannerActivity.getResultText(data)
val wasQrCode = QrCodeScannerActivity.getResultIsQrCode(data)
if (wasQrCode && !scannedQrCode.isNullOrBlank()) { if (wasQrCode && !scannedQrCode.isNullOrBlank()) {
onRemoteQrCodeScanned(scannedQrCode) onRemoteQrCodeScanned(scannedQrCode)
@ -110,8 +106,6 @@ class VerificationChooseMethodFragment @Inject constructor(
} }
} }
} }
}
}
private fun onRemoteQrCodeScanned(remoteQrCode: String) = withState(sharedViewModel) { state -> private fun onRemoteQrCodeScanned(remoteQrCode: String) = withState(sharedViewModel) { state ->
sharedViewModel.handle(VerificationAction.RemoteQrCodeScanned( sharedViewModel.handle(VerificationAction.RemoteQrCodeScanned(

View File

@ -16,7 +16,6 @@
package im.vector.app.features.discovery package im.vector.app.features.discovery
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
@ -27,16 +26,17 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.observeEvent import im.vector.app.core.extensions.observeEvent
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.ensureProtocol import im.vector.app.core.utils.ensureProtocol
import im.vector.app.features.discovery.change.SetIdentityServerFragment import im.vector.app.features.discovery.change.SetIdentityServerFragment
import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.settings.VectorSettingsActivity
import im.vector.app.features.terms.ReviewTermsActivity
import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.SharedState
import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.terms.TermsService
import kotlinx.android.synthetic.main.fragment_generic_recycler.* import kotlinx.android.synthetic.main.fragment_generic_recycler.*
import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
class DiscoverySettingsFragment @Inject constructor( class DiscoverySettingsFragment @Inject constructor(
@ -92,22 +92,19 @@ class DiscoverySettingsFragment @Inject constructor(
viewModel.handle(DiscoverySettingsAction.Refresh) viewModel.handle(DiscoverySettingsAction.Refresh)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val termsActivityResultLauncher = registerStartForActivityResult {
if (requestCode == ReviewTermsActivity.TERMS_REQUEST_CODE) { if (it.resultCode == Activity.RESULT_OK) {
if (Activity.RESULT_OK == resultCode) {
viewModel.handle(DiscoverySettingsAction.RetrieveBinding) viewModel.handle(DiscoverySettingsAction.RetrieveBinding)
} else { } else {
// add some error? // add some error?
} }
} }
super.onActivityResult(requestCode, resultCode, data)
}
override fun openIdentityServerTerms() = withState(viewModel) { state -> override fun openIdentityServerTerms() = withState(viewModel) { state ->
if (state.termsNotSigned) { if (state.termsNotSigned) {
navigator.openTerms( navigator.openTerms(
this, requireContext(),
termsActivityResultLauncher,
TermsService.ServiceType.IdentityService, TermsService.ServiceType.IdentityService,
state.identityServer()?.ensureProtocol() ?: "", state.identityServer()?.ensureProtocol() ?: "",
null) null)

View File

@ -16,7 +16,6 @@
package im.vector.app.features.discovery.change package im.vector.app.features.discovery.change
import android.app.Activity import android.app.Activity
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.inputmethod.EditorInfo import android.view.inputmethod.EditorInfo
@ -28,13 +27,13 @@ import com.airbnb.mvrx.withState
import com.jakewharton.rxbinding3.widget.textChanges import com.jakewharton.rxbinding3.widget.textChanges
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.toReducedUrl import im.vector.app.core.extensions.toReducedUrl
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.core.utils.colorizeMatchingText
import im.vector.app.features.discovery.DiscoverySharedViewModel import im.vector.app.features.discovery.DiscoverySharedViewModel
import im.vector.app.features.terms.ReviewTermsActivity
import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.terms.TermsService
import kotlinx.android.synthetic.main.fragment_set_identity_server.* import kotlinx.android.synthetic.main.fragment_set_identity_server.*
import javax.inject.Inject import javax.inject.Inject
@ -121,7 +120,8 @@ class SetIdentityServerFragment @Inject constructor(
is SetIdentityServerViewEvents.TermsAccepted -> processIdentityServerChange() is SetIdentityServerViewEvents.TermsAccepted -> processIdentityServerChange()
is SetIdentityServerViewEvents.ShowTerms -> { is SetIdentityServerViewEvents.ShowTerms -> {
navigator.openTerms( navigator.openTerms(
this, requireContext(),
termsActivityResultLauncher,
TermsService.ServiceType.IdentityService, TermsService.ServiceType.IdentityService,
it.identityServerUrl, it.identityServerUrl,
null) null)
@ -150,16 +150,13 @@ class SetIdentityServerFragment @Inject constructor(
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.identity_server) (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.identity_server)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val termsActivityResultLauncher = registerStartForActivityResult {
if (requestCode == ReviewTermsActivity.TERMS_REQUEST_CODE) { if (it.resultCode == Activity.RESULT_OK) {
if (Activity.RESULT_OK == resultCode) {
processIdentityServerChange() processIdentityServerChange()
} else { } else {
// add some error? // add some error?
} }
} }
super.onActivityResult(requestCode, resultCode, data)
}
private fun processIdentityServerChange() { private fun processIdentityServerChange() {
viewModel.currentWantedUrl?.let { viewModel.currentWantedUrl?.let {

View File

@ -17,7 +17,7 @@
package im.vector.app.features.home.room.detail package im.vector.app.features.home.room.detail
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity.RESULT_OK import android.app.Activity
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.graphics.Typeface import android.graphics.Typeface
@ -73,6 +73,7 @@ import im.vector.app.core.epoxy.LayoutManagerStateRestorer
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.extensions.showKeyboard import im.vector.app.core.extensions.showKeyboard
import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.extensions.trackItemsVisibilityChange
@ -134,7 +135,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet import im.vector.app.features.home.room.detail.timeline.reactions.ViewReactionsBottomSheet
import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet import im.vector.app.features.home.room.detail.widget.RoomWidgetsBottomSheet
import im.vector.app.features.home.room.detail.widget.WidgetRequestCodes
import im.vector.app.features.html.EventHtmlRenderer import im.vector.app.features.html.EventHtmlRenderer
import im.vector.app.features.html.PillImageSpan import im.vector.app.features.html.PillImageSpan
import im.vector.app.features.invite.VectorInviteView import im.vector.app.features.invite.VectorInviteView
@ -202,8 +202,6 @@ data class RoomDetailArgs(
val sharedData: SharedData? = null val sharedData: SharedData? = null
) : Parcelable ) : Parcelable
private const val REACTION_SELECT_REQUEST_CODE = 0
class RoomDetailFragment @Inject constructor( class RoomDetailFragment @Inject constructor(
private val session: Session, private val session: Session,
private val avatarRenderer: AvatarRenderer, private val avatarRenderer: AvatarRenderer,
@ -396,9 +394,14 @@ class RoomDetailFragment @Inject constructor(
} }
} }
private val integrationManagerActivityResultLauncher = registerStartForActivityResult {
// Noop
}
private fun openIntegrationManager(screen: String? = null) { private fun openIntegrationManager(screen: String? = null) {
navigator.openIntegrationManager( navigator.openIntegrationManager(
fragment = this, context = requireContext(),
activityResultLauncher = integrationManagerActivityResultLauncher,
roomId = roomDetailArgs.roomId, roomId = roomDetailArgs.roomId,
integId = null, integId = null,
screen = screen screen = screen
@ -435,7 +438,7 @@ class RoomDetailFragment @Inject constructor(
} }
private fun openStickerPicker(event: RoomDetailViewEvents.OpenStickerPicker) { private fun openStickerPicker(event: RoomDetailViewEvents.OpenStickerPicker) {
navigator.openStickerPicker(this, roomDetailArgs.roomId, event.widget) navigator.openStickerPicker(requireContext(), stickerActivityResultLauncher, roomDetailArgs.roomId, event.widget)
} }
private fun startOpenFileIntent(action: RoomDetailViewEvents.OpenFile) { private fun startOpenFileIntent(action: RoomDetailViewEvents.OpenFile) {
@ -886,28 +889,64 @@ class RoomDetailFragment @Inject constructor(
roomDetailViewModel.handle(RoomDetailAction.SaveDraft(composerLayout.composerEditText.text.toString())) roomDetailViewModel.handle(RoomDetailAction.SaveDraft(composerLayout.composerEditText.text.toString()))
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val attachmentFileActivityResultLauncher = registerStartForActivityResult {
val hasBeenHandled = attachmentsHelper.onActivityResult(requestCode, resultCode, data) if (it.resultCode == Activity.RESULT_OK) {
if (!hasBeenHandled && resultCode == RESULT_OK && data != null) { attachmentsHelper.onImageResult(it.data)
when (requestCode) { }
AttachmentsPreviewActivity.REQUEST_CODE -> { }
private val attachmentAudioActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
attachmentsHelper.onAudioResult(it.data)
}
}
private val attachmentContactActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
attachmentsHelper.onContactResult(it.data)
}
}
private val attachmentImageActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
attachmentsHelper.onImageResult(it.data)
}
}
private val attachmentPhotoActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
attachmentsHelper.onPhotoResult()
}
}
private val contentAttachmentActivityResultLauncher = registerStartForActivityResult { activityResult ->
val data = activityResult.data ?: return@registerStartForActivityResult
if (activityResult.resultCode == Activity.RESULT_OK) {
val sendData = AttachmentsPreviewActivity.getOutput(data) val sendData = AttachmentsPreviewActivity.getOutput(data)
val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data) val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data)
roomDetailViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize)) roomDetailViewModel.handle(RoomDetailAction.SendMedia(sendData, !keepOriginalSize))
} }
REACTION_SELECT_REQUEST_CODE -> { }
val (eventId, reaction) = EmojiReactionPickerActivity.getOutput(data) ?: return
private val emojiActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
val eventId = EmojiReactionPickerActivity.getOutputEventId(activityResult.data)
val reaction = EmojiReactionPickerActivity.getOutputReaction(activityResult.data)
if (eventId != null && reaction != null) {
roomDetailViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction)) roomDetailViewModel.handle(RoomDetailAction.SendReaction(eventId, reaction))
} }
WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE -> { }
val content = WidgetActivity.getOutput(data).toModel<MessageStickerContent>() ?: return }
private val stickerActivityResultLauncher = registerStartForActivityResult { activityResult ->
val data = activityResult.data ?: return@registerStartForActivityResult
if (activityResult.resultCode == Activity.RESULT_OK) {
WidgetActivity.getOutput(data).toModel<MessageStickerContent>()
?.let { content ->
roomDetailViewModel.handle(RoomDetailAction.SendSticker(content)) roomDetailViewModel.handle(RoomDetailAction.SendSticker(content))
} }
} }
} }
// TODO why don't we call super here?
// super.onActivityResult(requestCode, resultCode, data)
}
// PRIVATE METHODS ***************************************************************************** // PRIVATE METHODS *****************************************************************************
@ -1600,7 +1639,7 @@ class RoomDetailFragment @Inject constructor(
openRoomMemberProfile(action.userId) openRoomMemberProfile(action.userId)
} }
is EventSharedAction.AddReaction -> { is EventSharedAction.AddReaction -> {
startActivityForResult(EmojiReactionPickerActivity.intent(requireContext(), action.eventId), REACTION_SELECT_REQUEST_CODE) emojiActivityResultLauncher.launch(EmojiReactionPickerActivity.intent(requireContext(), action.eventId))
} }
is EventSharedAction.ViewReactions -> { is EventSharedAction.ViewReactions -> {
ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData) ViewReactionsBottomSheet.newInstance(roomDetailArgs.roomId, action.messageInformationData)
@ -1827,11 +1866,11 @@ class RoomDetailFragment @Inject constructor(
private fun launchAttachmentProcess(type: AttachmentTypeSelectorView.Type) { private fun launchAttachmentProcess(type: AttachmentTypeSelectorView.Type) {
when (type) { when (type) {
AttachmentTypeSelectorView.Type.CAMERA -> attachmentsHelper.openCamera(this) AttachmentTypeSelectorView.Type.CAMERA -> attachmentsHelper.openCamera(requireContext(), attachmentPhotoActivityResultLauncher)
AttachmentTypeSelectorView.Type.FILE -> attachmentsHelper.selectFile(this) AttachmentTypeSelectorView.Type.FILE -> attachmentsHelper.selectFile(attachmentFileActivityResultLauncher)
AttachmentTypeSelectorView.Type.GALLERY -> attachmentsHelper.selectGallery(this) AttachmentTypeSelectorView.Type.GALLERY -> attachmentsHelper.selectGallery(attachmentImageActivityResultLauncher)
AttachmentTypeSelectorView.Type.AUDIO -> attachmentsHelper.selectAudio(this) AttachmentTypeSelectorView.Type.AUDIO -> attachmentsHelper.selectAudio(attachmentAudioActivityResultLauncher)
AttachmentTypeSelectorView.Type.CONTACT -> attachmentsHelper.selectContact(this) AttachmentTypeSelectorView.Type.CONTACT -> attachmentsHelper.selectContact(attachmentContactActivityResultLauncher)
AttachmentTypeSelectorView.Type.STICKER -> roomDetailViewModel.handle(RoomDetailAction.SelectStickerAttachment) AttachmentTypeSelectorView.Type.STICKER -> roomDetailViewModel.handle(RoomDetailAction.SelectStickerAttachment)
}.exhaustive }.exhaustive
} }
@ -1850,7 +1889,7 @@ class RoomDetailFragment @Inject constructor(
} }
if (grouped.previewables.isNotEmpty()) { if (grouped.previewables.isNotEmpty()) {
val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(grouped.previewables)) val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(grouped.previewables))
startActivityForResult(intent, AttachmentsPreviewActivity.REQUEST_CODE) contentAttachmentActivityResultLauncher.launch(intent)
} }
} }
} }

View File

@ -1,22 +0,0 @@
/*
* Copyright (c) 2020 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.app.features.home.room.detail.widget
object WidgetRequestCodes {
const val STICKER_PICKER_REQUEST_CODE = 16000
const val INTEGRATION_MANAGER_REQUEST_CODE = 16001
}

View File

@ -112,6 +112,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (allGranted(grantResults)) { if (allGranted(grantResults)) {
if (requestCode == PERMISSION_REQUEST_CODE_READ_CONTACTS) { if (requestCode == PERMISSION_REQUEST_CODE_READ_CONTACTS) {
doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) } doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) }

View File

@ -133,7 +133,7 @@ class BigImageViewerActivity : VectorBaseActivity() {
MultiPicker.REQUEST_CODE_TAKE_PHOTO -> { MultiPicker.REQUEST_CODE_TAKE_PHOTO -> {
avatarCameraUri?.let { uri -> avatarCameraUri?.let { uri ->
MultiPicker.get(MultiPicker.CAMERA) MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(this, requestCode, resultCode, uri) .getTakenPhoto(this, uri)
?.let { ?.let {
onRoomAvatarSelected(it) onRoomAvatarSelected(it)
} }
@ -142,7 +142,7 @@ class BigImageViewerActivity : VectorBaseActivity() {
MultiPicker.REQUEST_CODE_PICK_IMAGE -> { MultiPicker.REQUEST_CODE_PICK_IMAGE -> {
MultiPicker MultiPicker
.get(MultiPicker.IMAGE) .get(MultiPicker.IMAGE)
.getSelectedFiles(this, requestCode, resultCode, data) .getSelectedFiles(this, data)
.firstOrNull()?.let { .firstOrNull()?.let {
onRoomAvatarSelected(it) onRoomAvatarSelected(it)
} }
@ -154,6 +154,7 @@ class BigImageViewerActivity : VectorBaseActivity() {
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (allGranted(grantResults)) { if (allGranted(grantResults)) {
when (requestCode) { when (requestCode) {
PERMISSION_REQUEST_CODE_LAUNCH_CAMERA -> onAvatarTypeSelected(true) PERMISSION_REQUEST_CODE_LAUNCH_CAMERA -> onAvatarTypeSelected(true)

View File

@ -21,11 +21,11 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
import android.view.Window import android.view.Window
import androidx.activity.result.ActivityResultLauncher
import androidx.core.app.ActivityOptionsCompat import androidx.core.app.ActivityOptionsCompat
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import androidx.core.util.Pair import androidx.core.util.Pair
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.fragment.app.Fragment
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.error.fatalError import im.vector.app.core.error.fatalError
@ -45,7 +45,6 @@ import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.RoomDetailArgs import im.vector.app.features.home.room.detail.RoomDetailArgs
import im.vector.app.features.home.room.detail.search.SearchActivity import im.vector.app.features.home.room.detail.search.SearchActivity
import im.vector.app.features.home.room.detail.search.SearchArgs import im.vector.app.features.home.room.detail.search.SearchArgs
import im.vector.app.features.home.room.detail.widget.WidgetRequestCodes
import im.vector.app.features.home.room.filtered.FilteredRoomsActivity import im.vector.app.features.home.room.filtered.FilteredRoomsActivity
import im.vector.app.features.invite.InviteUsersToRoomActivity import im.vector.app.features.invite.InviteUsersToRoomActivity
import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.AttachmentData
@ -266,21 +265,32 @@ class DefaultNavigator @Inject constructor(
} }
} }
override fun openTerms(fragment: Fragment, serviceType: TermsService.ServiceType, baseUrl: String, token: String?, requestCode: Int) { override fun openTerms(context: Context,
val intent = ReviewTermsActivity.intent(fragment.requireContext(), serviceType, baseUrl, token) activityResultLauncher: ActivityResultLauncher<Intent>,
fragment.startActivityForResult(intent, requestCode) serviceType: TermsService.ServiceType,
baseUrl: String,
token: String?) {
val intent = ReviewTermsActivity.intent(context, serviceType, baseUrl, token)
activityResultLauncher.launch(intent)
} }
override fun openStickerPicker(fragment: Fragment, roomId: String, widget: Widget, requestCode: Int) { override fun openStickerPicker(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
roomId: String,
widget: Widget) {
val widgetArgs = widgetArgsBuilder.buildStickerPickerArgs(roomId, widget) val widgetArgs = widgetArgsBuilder.buildStickerPickerArgs(roomId, widget)
val intent = WidgetActivity.newIntent(fragment.requireContext(), widgetArgs) val intent = WidgetActivity.newIntent(context, widgetArgs)
fragment.startActivityForResult(intent, WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE) activityResultLauncher.launch(intent)
} }
override fun openIntegrationManager(fragment: Fragment, roomId: String, integId: String?, screen: String?) { override fun openIntegrationManager(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
roomId: String,
integId: String?,
screen: String?) {
val widgetArgs = widgetArgsBuilder.buildIntegrationManagerArgs(roomId, integId, screen) val widgetArgs = widgetArgsBuilder.buildIntegrationManagerArgs(roomId, integId, screen)
val intent = WidgetActivity.newIntent(fragment.requireContext(), widgetArgs) val intent = WidgetActivity.newIntent(context, widgetArgs)
fragment.startActivityForResult(intent, WidgetRequestCodes.INTEGRATION_MANAGER_REQUEST_CODE) activityResultLauncher.launch(intent)
} }
override fun openRoomWidget(context: Context, roomId: String, widget: Widget, options: Map<String, Any>?) { override fun openRoomWidget(context: Context, roomId: String, widget: Widget, options: Map<String, Any>?) {
@ -293,9 +303,11 @@ class DefaultNavigator @Inject constructor(
} }
} }
override fun openPinCode(fragment: Fragment, pinMode: PinMode, requestCode: Int) { override fun openPinCode(context: Context,
val intent = PinActivity.newIntent(fragment.requireContext(), PinArgs(pinMode)) activityResultLauncher: ActivityResultLauncher<Intent>,
fragment.startActivityForResult(intent, requestCode) pinMode: PinMode) {
val intent = PinActivity.newIntent(context, PinArgs(pinMode))
activityResultLauncher.launch(intent)
} }
override fun openPinCode(activity: Activity, pinMode: PinMode, requestCode: Int) { override fun openPinCode(activity: Activity, pinMode: PinMode, requestCode: Int) {

View File

@ -18,18 +18,17 @@ package im.vector.app.features.navigation
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent
import android.view.View import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.core.util.Pair import androidx.core.util.Pair
import androidx.fragment.app.Fragment
import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.crypto.recover.SetupMode
import im.vector.app.features.home.room.detail.widget.WidgetRequestCodes
import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.AttachmentData
import im.vector.app.features.pin.PinActivity import im.vector.app.features.pin.PinActivity
import im.vector.app.features.pin.PinMode import im.vector.app.features.pin.PinMode
import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData import im.vector.app.features.roomdirectory.roompreview.RoomPreviewData
import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.settings.VectorSettingsActivity
import im.vector.app.features.share.SharedData import im.vector.app.features.share.SharedData
import im.vector.app.features.terms.ReviewTermsActivity
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom
import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData
import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.terms.TermsService
@ -84,22 +83,28 @@ interface Navigator {
fun openBigImageViewer(activity: Activity, sharedElement: View?, matrixItem: MatrixItem) fun openBigImageViewer(activity: Activity, sharedElement: View?, matrixItem: MatrixItem)
fun openPinCode(fragment: Fragment, pinMode: PinMode, requestCode: Int = PinActivity.PIN_REQUEST_CODE) fun openPinCode(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
pinMode: PinMode)
fun openPinCode(activity: Activity, pinMode: PinMode, requestCode: Int = PinActivity.PIN_REQUEST_CODE) fun openPinCode(activity: Activity, pinMode: PinMode, requestCode: Int = PinActivity.PIN_REQUEST_CODE)
fun openTerms(fragment: Fragment, fun openTerms(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
serviceType: TermsService.ServiceType, serviceType: TermsService.ServiceType,
baseUrl: String, baseUrl: String,
token: String?, token: String?)
requestCode: Int = ReviewTermsActivity.TERMS_REQUEST_CODE)
fun openStickerPicker(fragment: Fragment, fun openStickerPicker(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
roomId: String, roomId: String,
widget: Widget, widget: Widget)
requestCode: Int = WidgetRequestCodes.STICKER_PICKER_REQUEST_CODE)
fun openIntegrationManager(fragment: Fragment, roomId: String, integId: String?, screen: String?) fun openIntegrationManager(context: Context,
activityResultLauncher: ActivityResultLauncher<Intent>,
roomId: String,
integId: String?,
screen: String?)
fun openRoomWidget(context: Context, roomId: String, widget: Widget, options: Map<String, Any>? = null) fun openRoomWidget(context: Context, roomId: String, widget: Widget, options: Map<String, Any>? = null)

View File

@ -19,7 +19,7 @@ package im.vector.app.features.qrcode
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.fragment.app.Fragment import androidx.activity.result.ActivityResultLauncher
import com.google.zxing.BarcodeFormat import com.google.zxing.BarcodeFormat
import com.google.zxing.Result import com.google.zxing.Result
import com.google.zxing.ResultMetadataType import com.google.zxing.ResultMetadataType
@ -82,8 +82,8 @@ class QrCodeScannerActivity : VectorBaseActivity() {
activity.startActivityForResult(Intent(activity, QrCodeScannerActivity::class.java), requestCode) activity.startActivityForResult(Intent(activity, QrCodeScannerActivity::class.java), requestCode)
} }
fun startForResult(fragment: Fragment, requestCode: Int = QR_CODE_SCANNER_REQUEST_CODE) { fun startForResult(activity: Activity, activityResultLauncher: ActivityResultLauncher<Intent>) {
fragment.startActivityForResult(Intent(fragment.requireActivity(), QrCodeScannerActivity::class.java), requestCode) activityResultLauncher.launch(Intent(activity, QrCodeScannerActivity::class.java))
} }
fun getResultText(data: Intent?): String? { fun getResultText(data: Intent?): String? {

View File

@ -212,10 +212,8 @@ class EmojiReactionPickerActivity : VectorBaseActivity(),
return intent return intent
} }
fun getOutput(data: Intent): Pair<String, String>? { fun getOutputEventId(data: Intent?): String? = data?.getStringExtra(EXTRA_EVENT_ID)
val eventId = data.getStringExtra(EXTRA_EVENT_ID) ?: return null
val reaction = data.getStringExtra(EXTRA_REACTION_RESULT) ?: return null fun getOutputReaction(data: Intent?): String? = data?.getStringExtra(EXTRA_REACTION_RESULT)
return eventId to reaction
}
} }
} }

View File

@ -42,6 +42,7 @@ import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.copyOnLongClick import im.vector.app.core.extensions.copyOnLongClick
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
@ -284,7 +285,7 @@ class RoomProfileFragment @Inject constructor(
.show() .show()
} }
private val takePhotoActivityResultLauncher = registerForPermissionsResult { allGranted -> private val takePhotoPermissionActivityResultLauncher = registerForPermissionsResult { allGranted ->
if (allGranted) { if (allGranted) {
onAvatarTypeSelected(true) onAvatarTypeSelected(true)
} }
@ -293,11 +294,11 @@ class RoomProfileFragment @Inject constructor(
private var avatarCameraUri: Uri? = null private var avatarCameraUri: Uri? = null
private fun onAvatarTypeSelected(isCamera: Boolean) { private fun onAvatarTypeSelected(isCamera: Boolean) {
if (isCamera) { if (isCamera) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), takePhotoActivityResultLauncher)) { if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), takePhotoPermissionActivityResultLauncher)) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(this) avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(requireActivity(), takePhotoActivityResultLauncher)
} }
} else { } else {
MultiPicker.get(MultiPicker.IMAGE).single().startWith(this) MultiPicker.get(MultiPicker.IMAGE).single().startWith(pickImageActivityResultLauncher)
} }
} }
@ -309,30 +310,37 @@ class RoomProfileFragment @Inject constructor(
.start(requireContext(), this) .start(requireContext(), this)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val takePhotoActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (resultCode == Activity.RESULT_OK) { if (activityResult.resultCode == Activity.RESULT_OK) {
when (requestCode) {
MultiPicker.REQUEST_CODE_TAKE_PHOTO -> {
avatarCameraUri?.let { uri -> avatarCameraUri?.let { uri ->
MultiPicker.get(MultiPicker.CAMERA) MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(requireContext(), requestCode, resultCode, uri) .getTakenPhoto(requireContext(), uri)
?.let { ?.let {
onRoomAvatarSelected(it) onRoomAvatarSelected(it)
} }
} }
} }
MultiPicker.REQUEST_CODE_PICK_IMAGE -> { }
private val pickImageActivityResultLauncher = registerStartForActivityResult { activityResult ->
if (activityResult.resultCode == Activity.RESULT_OK) {
MultiPicker MultiPicker
.get(MultiPicker.IMAGE) .get(MultiPicker.IMAGE)
.getSelectedFiles(requireContext(), requestCode, resultCode, data) .getSelectedFiles(requireContext(), activityResult.data)
.firstOrNull()?.let { .firstOrNull()?.let {
onRoomAvatarSelected(it) onRoomAvatarSelected(it)
} }
} }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) } UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) }
BigImageViewerActivity.REQUEST_CODE -> data?.let { onAvatarCropped(it.data) } BigImageViewerActivity.REQUEST_CODE -> data?.let { onAvatarCropped(it.data) }
} }
} }
// TODO
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
} }

View File

@ -41,6 +41,7 @@ import com.google.android.material.textfield.TextInputLayout
import com.yalantis.ucrop.UCrop import com.yalantis.ucrop.UCrop
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hideKeyboard
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.showPassword import im.vector.app.core.extensions.showPassword
import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getFilenameFromUri
import im.vector.app.core.platform.SimpleTextWatcher import im.vector.app.core.platform.SimpleTextWatcher
@ -278,81 +279,38 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
session.integrationManagerService().removeListener(integrationServiceListener) session.integrationManagerService().removeListener(integrationServiceListener)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val attachmentPhotoActivityResultLauncher = registerStartForActivityResult {activityResult ->
super.onActivityResult(requestCode, resultCode, data) if (activityResult.resultCode == Activity.RESULT_OK) {
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQUEST_NEW_PHONE_NUMBER -> refreshPhoneNumbersList()
REQUEST_PHONEBOOK_COUNTRY -> onPhonebookCountryUpdate(data)
MultiPicker.REQUEST_CODE_TAKE_PHOTO -> {
avatarCameraUri?.let { uri -> avatarCameraUri?.let { uri ->
MultiPicker.get(MultiPicker.CAMERA) MultiPicker.get(MultiPicker.CAMERA)
.getTakenPhoto(requireContext(), requestCode, resultCode, uri) .getTakenPhoto(requireContext(), uri)
?.let { ?.let {
onAvatarSelected(it) onAvatarSelected(it)
} }
} }
} }
MultiPicker.REQUEST_CODE_PICK_IMAGE -> { }
private val attachmentImageActivityResultLauncher = registerStartForActivityResult {activityResult ->
val data = activityResult.data ?: return@registerStartForActivityResult
if (activityResult.resultCode == Activity.RESULT_OK) {
MultiPicker MultiPicker
.get(MultiPicker.IMAGE) .get(MultiPicker.IMAGE)
.getSelectedFiles(requireContext(), requestCode, resultCode, data) .getSelectedFiles(requireContext(), data)
.firstOrNull()?.let { .firstOrNull()?.let {
onAvatarSelected(it) onAvatarSelected(it)
} }
} }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@Suppress("DEPRECATION")
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
// TODO Migrate this too
UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) } UCrop.REQUEST_CROP -> data?.let { onAvatarCropped(UCrop.getOutput(it)) }
/* TODO
VectorUtils.TAKE_IMAGE -> {
val thumbnailUri = VectorUtils.getThumbnailUriFromIntent(activity, data, session.mediaCache)
if (null != thumbnailUri) {
displayLoadingView()
val resource = ResourceUtils.openResource(activity, thumbnailUri, null)
if (null != resource) {
session.mediaCache.uploadContent(resource.mContentStream, null, resource.mMimeType, null, object : MXMediaUploadListener() {
override fun onUploadError(uploadId: String?, serverResponseCode: Int, serverErrorMessage: String?) {
activity?.runOnUiThread { onCommonDone(serverResponseCode.toString() + " : " + serverErrorMessage) }
}
override fun onUploadComplete(uploadId: String?, contentUri: String?) {
activity?.runOnUiThread {
session.myUser.updateAvatarUrl(contentUri, object : MatrixCallback<Unit> {
override fun onSuccess(info: Void?) {
onCommonDone(null)
refreshDisplay()
}
override fun onNetworkError(e: Exception) {
onCommonDone(e.localizedMessage)
}
override fun onMatrixError(e: MatrixError) {
if (MatrixError.M_CONSENT_NOT_GIVEN == e.errcode) {
activity?.runOnUiThread {
hideLoadingView()
(activity as VectorAppCompatActivity).consentNotGivenHelper.displayDialog(e)
}
} else {
onCommonDone(e.localizedMessage)
}
}
override fun onUnexpectedError(e: Exception) {
onCommonDone(e.localizedMessage)
}
})
}
}
})
}
}
}
*/
} }
} }
} }
@ -400,10 +358,10 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
private fun onAvatarTypeSelected(isCamera: Boolean) { private fun onAvatarTypeSelected(isCamera: Boolean) {
if (isCamera) { if (isCamera) {
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), takePhotoActivityResultLauncher)) { if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), takePhotoActivityResultLauncher)) {
avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(this) avatarCameraUri = MultiPicker.get(MultiPicker.CAMERA).startWithExpectingFile(requireActivity(), attachmentPhotoActivityResultLauncher)
} }
} else { } else {
MultiPicker.get(MultiPicker.IMAGE).single().startWith(this) MultiPicker.get(MultiPicker.IMAGE).single().startWith(attachmentImageActivityResultLauncher)
} }
} }
@ -461,29 +419,10 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
*/ */
} }
private fun onPhonebookCountryUpdate(data: Intent?) {
/* TODO
if (data != null && data.hasExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_NAME)
&& data.hasExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_CODE)) {
val countryCode = data.getStringExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_CODE)
if (!TextUtils.equals(countryCode, PhoneNumberUtils.getCountryCode(activity))) {
PhoneNumberUtils.setCountryCode(activity, countryCode)
mContactPhonebookCountryPreference.summary = data.getStringExtra(CountryPickerActivity.EXTRA_OUT_COUNTRY_NAME)
}
}
*/
}
// ============================================================================================================== // ==============================================================================================================
// Phone number management // Phone number management
// ============================================================================================================== // ==============================================================================================================
/**
* Refresh phone number list
*/
private fun refreshPhoneNumbersList() {
}
/** /**
* Update the password. * Update the password.
*/ */
@ -643,9 +582,4 @@ class VectorSettingsGeneralFragment : VectorSettingsBaseFragment() {
}) })
} }
} }
companion object {
private const val REQUEST_NEW_PHONE_NUMBER = 456
private const val REQUEST_PHONEBOOK_COUNTRY = 789
}
} }

View File

@ -16,14 +16,13 @@
package im.vector.app.features.settings package im.vector.app.features.settings
import android.content.Intent
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.notifications.NotificationDrawerManager import im.vector.app.features.notifications.NotificationDrawerManager
import im.vector.app.features.pin.PinActivity
import im.vector.app.features.pin.PinCodeStore import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.PinMode import im.vector.app.features.pin.PinMode
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -67,17 +66,18 @@ class VectorSettingsPinFragment @Inject constructor(
refreshPinCodeStatus() refreshPinCodeStatus()
} }
} else { } else {
navigator.openPinCode(this@VectorSettingsPinFragment, PinMode.CREATE) navigator.openPinCode(
requireContext(),
pinActivityResultLauncher,
PinMode.CREATE
)
} }
true true
} }
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val pinActivityResultLauncher = registerStartForActivityResult {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PinActivity.PIN_REQUEST_CODE) {
refreshPinCodeStatus() refreshPinCodeStatus()
} }
} }
}

View File

@ -39,6 +39,7 @@ import im.vector.app.R
import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.dialogs.ExportKeysDialog
import im.vector.app.core.extensions.queryExportKeys import im.vector.app.core.extensions.queryExportKeys
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.extensions.showPassword import im.vector.app.core.extensions.showPassword
import im.vector.app.core.intent.ExternalIntentData import im.vector.app.core.intent.ExternalIntentData
import im.vector.app.core.intent.analyseIntent import im.vector.app.core.intent.analyseIntent
@ -55,7 +56,6 @@ import im.vector.app.features.crypto.keysbackup.settings.KeysBackupManageActivit
import im.vector.app.features.crypto.recover.BootstrapBottomSheet import im.vector.app.features.crypto.recover.BootstrapBottomSheet
import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.crypto.recover.SetupMode
import im.vector.app.features.navigation.Navigator import im.vector.app.features.navigation.Navigator
import im.vector.app.features.pin.PinActivity
import im.vector.app.features.pin.PinCodeStore import im.vector.app.features.pin.PinCodeStore
import im.vector.app.features.pin.PinMode import im.vector.app.features.pin.PinMode
import im.vector.app.features.raw.wellknown.getElementWellknown import im.vector.app.features.raw.wellknown.getElementWellknown
@ -320,15 +320,10 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val saveMegolmStartForActivityResult = registerStartForActivityResult {
super.onActivityResult(requestCode, resultCode, data) val uri = it.data?.data ?: return@registerStartForActivityResult
if (resultCode == Activity.RESULT_OK) { if (it.resultCode == Activity.RESULT_OK)
when (requestCode) { ExportKeysDialog().show(requireActivity(), object : ExportKeysDialog.ExportKeyDialogListener {
REQUEST_CODE_SAVE_MEGOLM_EXPORT -> {
val uri = data?.data
if (uri != null) {
activity?.let { activity ->
ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
override fun onPassphrase(passphrase: String) { override fun onPassphrase(passphrase: String) {
displayLoadingView() displayLoadingView()
@ -353,23 +348,28 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
} }
}) })
} }
}
} private val pinActivityResultLauncher = registerStartForActivityResult {
PinActivity.PIN_REQUEST_CODE -> { if (it.resultCode == Activity.RESULT_OK) {
doOpenPinCodePreferenceScreen() doOpenPinCodePreferenceScreen()
} }
REQUEST_E2E_FILE_REQUEST_CODE -> { }
private val importKeysActivityResultLauncher = registerStartForActivityResult {
val data = it.data ?: return@registerStartForActivityResult
if (it.resultCode == Activity.RESULT_OK) {
importKeys(data) importKeys(data)
} }
} }
}
}
private fun openPinCodePreferenceScreen() { private fun openPinCodePreferenceScreen() {
lifecycleScope.launchWhenResumed { lifecycleScope.launchWhenResumed {
val hasPinCode = pinCodeStore.hasEncodedPin() val hasPinCode = pinCodeStore.hasEncodedPin()
if (hasPinCode) { if (hasPinCode) {
navigator.openPinCode(this@VectorSettingsSecurityPrivacyFragment, PinMode.AUTH) navigator.openPinCode(
requireContext(),
pinActivityResultLauncher,
PinMode.AUTH)
} else { } else {
doOpenPinCodePreferenceScreen() doOpenPinCodePreferenceScreen()
} }
@ -391,7 +391,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
} }
exportPref.onPreferenceClickListener = Preference.OnPreferenceClickListener { exportPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
queryExportKeys(activeSessionHolder.getSafeActiveSession()?.myUserId ?: "", REQUEST_CODE_SAVE_MEGOLM_EXPORT) queryExportKeys(activeSessionHolder.getSafeActiveSession()?.myUserId ?: "", saveMegolmStartForActivityResult)
true true
} }
@ -406,7 +406,12 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
*/ */
@SuppressLint("NewApi") @SuppressLint("NewApi")
private fun importKeys() { private fun importKeys() {
activity?.let { openFileSelection(it, this, false, REQUEST_E2E_FILE_REQUEST_CODE) } openFileSelection(
requireActivity(),
importKeysActivityResultLauncher,
false,
0
)
} }
/** /**
@ -414,12 +419,7 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
* *
* @param intent the intent result * @param intent the intent result
*/ */
private fun importKeys(intent: Intent?) { private fun importKeys(intent: Intent) {
// sanity check
if (null == intent) {
return
}
val sharedDataItems = analyseIntent(intent) val sharedDataItems = analyseIntent(intent)
val thisActivity = activity val thisActivity = activity
@ -605,9 +605,4 @@ class VectorSettingsSecurityPrivacyFragment @Inject constructor(
} }
}) })
} }
companion object {
private const val REQUEST_E2E_FILE_REQUEST_CODE = 123
private const val REQUEST_CODE_SAVE_MEGOLM_EXPORT = 124
}
} }

View File

@ -33,6 +33,7 @@ import im.vector.app.core.di.ActiveSessionHolder
import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.cleanup
import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.configureWith
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.AttachmentsHelper
import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity
@ -118,22 +119,18 @@ class IncomingShareFragment @Inject constructor(
private fun handleEditMediaBeforeSending(event: IncomingShareViewEvents.EditMediaBeforeSending) { private fun handleEditMediaBeforeSending(event: IncomingShareViewEvents.EditMediaBeforeSending) {
val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(event.contentAttachmentData)) val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(event.contentAttachmentData))
startActivityForResult(intent, AttachmentsPreviewActivity.REQUEST_CODE) attachmentPreviewActivityResultLauncher.launch(intent)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val attachmentPreviewActivityResultLauncher = registerStartForActivityResult {
val hasBeenHandled = attachmentsHelper.onActivityResult(requestCode, resultCode, data) val data = it.data ?: return@registerStartForActivityResult
if (!hasBeenHandled && resultCode == Activity.RESULT_OK && data != null) { if (it.resultCode == Activity.RESULT_OK) {
when (requestCode) {
AttachmentsPreviewActivity.REQUEST_CODE -> {
val sendData = AttachmentsPreviewActivity.getOutput(data) val sendData = AttachmentsPreviewActivity.getOutput(data)
val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data) val keepOriginalSize = AttachmentsPreviewActivity.getKeepOriginalSize(data)
viewModel.handle(IncomingShareAction.UpdateSharedData(SharedData.Attachments(sendData))) viewModel.handle(IncomingShareAction.UpdateSharedData(SharedData.Attachments(sendData)))
viewModel.handle(IncomingShareAction.ShareMedia(keepOriginalSize)) viewModel.handle(IncomingShareAction.ShareMedia(keepOriginalSize))
} }
} }
}
}
private fun handleShareToRoom(event: IncomingShareViewEvents.ShareToRoom) { private fun handleShareToRoom(event: IncomingShareViewEvents.ShareToRoom) {
if (event.showAlert) { if (event.showAlert) {

View File

@ -73,7 +73,6 @@ class ReviewTermsActivity : SimpleFragmentActivity() {
} }
companion object { companion object {
const val TERMS_REQUEST_CODE = 15000
private const val EXTRA_INFO = "EXTRA_INFO" private const val EXTRA_INFO = "EXTRA_INFO"
fun intent(context: Context, serviceType: TermsService.ServiceType, baseUrl: String, token: String?): Intent { fun intent(context: Context, serviceType: TermsService.ServiceType, baseUrl: String, token: String?): Intent {

View File

@ -37,11 +37,10 @@ import com.airbnb.mvrx.args
import com.airbnb.mvrx.withState import com.airbnb.mvrx.withState
import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.session.terms.TermsService
import im.vector.app.R import im.vector.app.R
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.OnBackPressed
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.utils.openUrlInExternalBrowser import im.vector.app.core.utils.openUrlInExternalBrowser
import im.vector.app.features.home.room.detail.widget.WidgetRequestCodes
import im.vector.app.features.terms.ReviewTermsActivity
import im.vector.app.features.webview.WebViewEventListener import im.vector.app.features.webview.WebViewEventListener
import im.vector.app.features.widgets.webview.clearAfterWidget import im.vector.app.features.widgets.webview.clearAfterWidget
import im.vector.app.features.widgets.webview.setupForWidget import im.vector.app.features.widgets.webview.setupForWidget
@ -86,21 +85,20 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
viewModel.handle(WidgetAction.LoadFormattedUrl) viewModel.handle(WidgetAction.LoadFormattedUrl)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val termsActivityResultLauncher = registerStartForActivityResult {
when (requestCode) {
ReviewTermsActivity.TERMS_REQUEST_CODE -> {
Timber.v("On terms results") Timber.v("On terms results")
if (resultCode == Activity.RESULT_OK) { if (it.resultCode == Activity.RESULT_OK) {
viewModel.handle(WidgetAction.OnTermsReviewed) viewModel.handle(WidgetAction.OnTermsReviewed)
} else { } else {
vectorBaseActivity.finish() vectorBaseActivity.finish()
} }
} }
WidgetRequestCodes.INTEGRATION_MANAGER_REQUEST_CODE -> {
private val integrationManagerActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
viewModel.handle(WidgetAction.LoadFormattedUrl) viewModel.handle(WidgetAction.LoadFormattedUrl)
} }
} }
}
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
@ -146,7 +144,12 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) { state -> override fun onOptionsItemSelected(item: MenuItem): Boolean = withState(viewModel) { state ->
when (item.itemId) { when (item.itemId) {
R.id.action_edit -> { R.id.action_edit -> {
navigator.openIntegrationManager(this, state.roomId, state.widgetId, state.widgetKind.screenId) navigator.openIntegrationManager(
requireContext(),
integrationManagerActivityResultLauncher,
state.roomId,
state.widgetId,
state.widgetKind.screenId)
return@withState true return@withState true
} }
R.id.action_delete -> { R.id.action_delete -> {
@ -261,7 +264,8 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
private fun displayTerms(displayTerms: WidgetViewEvents.DisplayTerms) { private fun displayTerms(displayTerms: WidgetViewEvents.DisplayTerms) {
navigator.openTerms( navigator.openTerms(
fragment = this, context = requireContext(),
activityResultLauncher = termsActivityResultLauncher,
serviceType = TermsService.ServiceType.IntegrationManager, serviceType = TermsService.ServiceType.IntegrationManager,
baseUrl = displayTerms.url, baseUrl = displayTerms.url,
token = displayTerms.token token = displayTerms.token
@ -287,7 +291,8 @@ class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventL
private fun displayIntegrationManager(event: WidgetViewEvents.DisplayIntegrationManager) { private fun displayIntegrationManager(event: WidgetViewEvents.DisplayIntegrationManager) {
navigator.openIntegrationManager( navigator.openIntegrationManager(
fragment = this, context = requireContext(),
activityResultLauncher = integrationManagerActivityResultLauncher,
roomId = fragmentArgs.roomId, roomId = fragmentArgs.roomId,
integId = event.integId, integId = event.integId,
screen = event.integType screen = event.integType

View File

@ -18,7 +18,6 @@ package im.vector.app.features.workers.signout
import android.app.Activity import android.app.Activity
import android.app.Dialog import android.app.Dialog
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -39,6 +38,7 @@ import im.vector.app.R
import im.vector.app.core.di.ScreenComponent import im.vector.app.core.di.ScreenComponent
import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.dialogs.ExportKeysDialog
import im.vector.app.core.extensions.queryExportKeys import im.vector.app.core.extensions.queryExportKeys
import im.vector.app.core.extensions.registerStartForActivityResult
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity
import im.vector.app.features.crypto.recover.BootstrapBottomSheet import im.vector.app.features.crypto.recover.BootstrapBottomSheet
@ -77,9 +77,6 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(),
companion object { companion object {
fun newInstance() = SignOutBottomSheetDialogFragment() fun newInstance() = SignOutBottomSheetDialogFragment()
private const val EXPORT_REQ = 0
private const val QUERY_EXPORT_KEYS = 1
} }
init { init {
@ -130,12 +127,12 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(),
exportManuallyButton.action = { exportManuallyButton.action = {
withState(viewModel) { state -> withState(viewModel) { state ->
queryExportKeys(state.userId, QUERY_EXPORT_KEYS) queryExportKeys(state.userId, manualExportKeysActivityResultLauncher)
} }
} }
setupMegolmBackupButton.action = { setupMegolmBackupButton.action = {
startActivityForResult(KeysBackupSetupActivity.intent(requireContext(), true), EXPORT_REQ) setupBackupActivityResultLauncher.launch(KeysBackupSetupActivity.intent(requireContext(), true))
} }
viewModel.observeViewEvents { viewModel.observeViewEvents {
@ -289,13 +286,10 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(),
return dialog return dialog
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { private val manualExportKeysActivityResultLauncher = registerStartForActivityResult {
super.onActivityResult(requestCode, resultCode, data) if (it.resultCode == Activity.RESULT_OK) {
val uri = it.data?.data
if (resultCode == Activity.RESULT_OK) { if (uri != null) {
if (requestCode == QUERY_EXPORT_KEYS) {
val uri = data?.data
if (resultCode == Activity.RESULT_OK && uri != null) {
activity?.let { activity -> activity?.let { activity ->
ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener { ExportKeysDialog().show(activity, object : ExportKeysDialog.ExportKeyDialogListener {
override fun onPassphrase(passphrase: String) { override fun onPassphrase(passphrase: String) {
@ -304,11 +298,14 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(),
}) })
} }
} }
} else if (requestCode == EXPORT_REQ) { }
if (data?.getBooleanExtra(KeysBackupSetupActivity.MANUAL_EXPORT, false) == true) { }
private val setupBackupActivityResultLauncher = registerStartForActivityResult {
if (it.resultCode == Activity.RESULT_OK) {
if (it.data?.getBooleanExtra(KeysBackupSetupActivity.MANUAL_EXPORT, false) == true) {
viewModel.handle(SignoutCheckViewModel.Actions.KeySuccessfullyManuallyExported) viewModel.handle(SignoutCheckViewModel.Actions.KeySuccessfullyManuallyExported)
} }
} }
} }
} }
}