Migrate to ViewBindings (#1072) - WIP
This commit is contained in:
parent
838340bbc8
commit
706736273c
|
@ -23,7 +23,7 @@ Test:
|
|||
-
|
||||
|
||||
Other changes:
|
||||
-
|
||||
- Migrate to ViewBindings (#1072)
|
||||
|
||||
Changes in Element 1.0.12 (2020-12-15)
|
||||
===================================================
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
|
@ -55,6 +54,10 @@ android {
|
|||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -33,7 +33,8 @@ import androidx.core.view.isVisible
|
|||
import androidx.core.view.updatePadding
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import kotlinx.android.synthetic.main.activity_attachment_viewer.*
|
||||
import im.vector.lib.attachmentviewer.databinding.ActivityAttachmentViewerBinding
|
||||
|
||||
import java.lang.ref.WeakReference
|
||||
import kotlin.math.abs
|
||||
|
||||
|
@ -50,12 +51,14 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
private var overlayView: View? = null
|
||||
set(value) {
|
||||
if (value == overlayView) return
|
||||
overlayView?.let { rootContainer.removeView(it) }
|
||||
rootContainer.addView(value)
|
||||
overlayView?.let { views.rootContainer.removeView(it) }
|
||||
views.rootContainer.addView(value)
|
||||
value?.updatePadding(top = topInset, bottom = bottomInset)
|
||||
field = value
|
||||
}
|
||||
|
||||
private lateinit var views: ActivityAttachmentViewerBinding
|
||||
|
||||
private lateinit var swipeDismissHandler: SwipeToDismissHandler
|
||||
private lateinit var directionDetector: SwipeDirectionDetector
|
||||
private lateinit var scaleDetector: ScaleGestureDetector
|
||||
|
@ -95,17 +98,18 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
|
||||
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
|
||||
|
||||
setContentView(R.layout.activity_attachment_viewer)
|
||||
attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
|
||||
views = ActivityAttachmentViewerBinding.inflate(layoutInflater)
|
||||
setContentView(views.root)
|
||||
views.attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
|
||||
attachmentsAdapter = AttachmentsAdapter()
|
||||
attachmentPager.adapter = attachmentsAdapter
|
||||
imageTransitionView = transitionImageView
|
||||
views.attachmentPager.adapter = attachmentsAdapter
|
||||
imageTransitionView = views.transitionImageView
|
||||
transitionImageContainer = findViewById(R.id.transitionImageContainer)
|
||||
pager2 = attachmentPager
|
||||
pager2 = views.attachmentPager
|
||||
directionDetector = createSwipeDirectionDetector()
|
||||
gestureDetector = createGestureDetector()
|
||||
|
||||
attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
views.attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
isImagePagerIdle = state == ViewPager2.SCROLL_STATE_IDLE
|
||||
}
|
||||
|
@ -116,12 +120,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
})
|
||||
|
||||
swipeDismissHandler = createSwipeToDismissHandler()
|
||||
rootContainer.setOnTouchListener(swipeDismissHandler)
|
||||
rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = dismissContainer.height / 4 }
|
||||
views.rootContainer.setOnTouchListener(swipeDismissHandler)
|
||||
views.rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = views.dismissContainer.height / 4 }
|
||||
|
||||
scaleDetector = createScaleGestureDetector()
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(rootContainer) { _, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(views.rootContainer) { _, insets ->
|
||||
overlayView?.updatePadding(top = insets.systemWindowInsetTop, bottom = insets.systemWindowInsetBottom)
|
||||
topInset = insets.systemWindowInsetTop
|
||||
bottomInset = insets.systemWindowInsetBottom
|
||||
|
@ -170,7 +174,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
if (swipeDirection == null && (scaleDetector.isInProgress || ev.pointerCount > 1 || wasScaled)) {
|
||||
wasScaled = true
|
||||
// Log.v("ATTACHEMENTS", "dispatch to pager")
|
||||
return attachmentPager.dispatchTouchEvent(ev)
|
||||
return views.attachmentPager.dispatchTouchEvent(ev)
|
||||
}
|
||||
|
||||
// Log.v("ATTACHEMENTS", "is current item scaled ${isScaled()}")
|
||||
|
@ -196,16 +200,16 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
private fun handleEventActionDown(event: MotionEvent) {
|
||||
swipeDirection = null
|
||||
wasScaled = false
|
||||
attachmentPager.dispatchTouchEvent(event)
|
||||
views.attachmentPager.dispatchTouchEvent(event)
|
||||
|
||||
swipeDismissHandler.onTouch(rootContainer, event)
|
||||
swipeDismissHandler.onTouch(views.rootContainer, event)
|
||||
isOverlayWasClicked = dispatchOverlayTouch(event)
|
||||
}
|
||||
|
||||
private fun handleEventActionUp(event: MotionEvent) {
|
||||
// wasDoubleTapped = false
|
||||
swipeDismissHandler.onTouch(rootContainer, event)
|
||||
attachmentPager.dispatchTouchEvent(event)
|
||||
swipeDismissHandler.onTouch(views.rootContainer, event)
|
||||
views.attachmentPager.dispatchTouchEvent(event)
|
||||
isOverlayWasClicked = dispatchOverlayTouch(event)
|
||||
}
|
||||
|
||||
|
@ -220,12 +224,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
private fun toggleOverlayViewVisibility() {
|
||||
if (systemUiVisibility) {
|
||||
// we hide
|
||||
TransitionManager.beginDelayedTransition(rootContainer)
|
||||
TransitionManager.beginDelayedTransition(views.rootContainer)
|
||||
hideSystemUI()
|
||||
overlayView?.isVisible = false
|
||||
} else {
|
||||
// we show
|
||||
TransitionManager.beginDelayedTransition(rootContainer)
|
||||
TransitionManager.beginDelayedTransition(views.rootContainer)
|
||||
showSystemUI()
|
||||
overlayView?.isVisible = true
|
||||
}
|
||||
|
@ -238,11 +242,11 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
return when (swipeDirection) {
|
||||
SwipeDirection.Up, SwipeDirection.Down -> {
|
||||
if (isSwipeToDismissAllowed && !wasScaled && isImagePagerIdle) {
|
||||
swipeDismissHandler.onTouch(rootContainer, event)
|
||||
swipeDismissHandler.onTouch(views.rootContainer, event)
|
||||
} else true
|
||||
}
|
||||
SwipeDirection.Left, SwipeDirection.Right -> {
|
||||
attachmentPager.dispatchTouchEvent(event)
|
||||
views.attachmentPager.dispatchTouchEvent(event)
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
|
@ -250,8 +254,8 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
|
||||
private fun handleSwipeViewMove(translationY: Float, translationLimit: Int) {
|
||||
val alpha = calculateTranslationAlpha(translationY, translationLimit)
|
||||
backgroundView.alpha = alpha
|
||||
dismissContainer.alpha = alpha
|
||||
views.backgroundView.alpha = alpha
|
||||
views.dismissContainer.alpha = alpha
|
||||
overlayView?.alpha = alpha
|
||||
}
|
||||
|
||||
|
@ -265,7 +269,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
|
|||
|
||||
private fun createSwipeToDismissHandler()
|
||||
: SwipeToDismissHandler = SwipeToDismissHandler(
|
||||
swipeView = dismissContainer,
|
||||
swipeView = views.dismissContainer,
|
||||
shouldAnimateDismiss = { shouldAnimateDismiss() },
|
||||
onDismiss = { animateClose() },
|
||||
onSwipeViewMove = ::handleSwipeViewMove)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'realm-android'
|
||||
|
||||
buildscript {
|
||||
|
@ -13,10 +13,6 @@ buildscript {
|
|||
}
|
||||
}
|
||||
|
||||
androidExtensions {
|
||||
experimental = true
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
testOptions.unitTests.includeAndroidResources = true
|
||||
|
|
|
@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.auth.data
|
|||
import android.os.Parcelable
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
@Parcelize
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.net.Uri
|
|||
import android.os.Parcelable
|
||||
import androidx.exifinterface.media.ExifInterface
|
||||
import com.squareup.moshi.JsonClass
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.matrix.android.sdk.api.util.MimeTypes.normalizeMimeType
|
||||
|
||||
@Parcelize
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package org.matrix.android.sdk.internal.auth.registration
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* This class represent a localized privacy policy for registration Flow.
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.attachments
|
|||
|
||||
import android.os.Parcelable
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? {
|
||||
// Check the validity of some fields
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
|
|
|
@ -3,7 +3,7 @@ package ${escapeKotlinIdentifiers(packageName)}
|
|||
import android.os.Bundle
|
||||
<#if createFragmentArgs>
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import com.airbnb.mvrx.args
|
||||
</#if>
|
||||
import android.view.View
|
||||
|
|
|
@ -3,17 +3,13 @@ import com.android.build.OutputFile
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
kapt {
|
||||
correctErrorTypes = true
|
||||
}
|
||||
|
||||
androidExtensions {
|
||||
experimental = true
|
||||
}
|
||||
|
||||
// Note: 2 digits max for each value
|
||||
ext.versionMajor = 1
|
||||
ext.versionMinor = 0
|
||||
|
@ -280,6 +276,10 @@ android {
|
|||
java.srcDirs += "src/sharedTest/java"
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -24,7 +24,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|||
import com.google.android.material.snackbar.Snackbar
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.utils.toast
|
||||
import kotlinx.android.synthetic.debug.activity_test_material_theme.*
|
||||
|
||||
|
||||
// Rendering is not the same with VectorBaseActivity
|
||||
abstract class DebugMaterialThemeActivity : AppCompatActivity() {
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.app.NotificationChannel
|
|||
import android.app.NotificationManager
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.view.LayoutInflater
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.content.getSystemService
|
||||
|
@ -34,16 +35,17 @@ import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
|
|||
import im.vector.app.core.utils.allGranted
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.ActivityDebugMenuBinding
|
||||
import im.vector.app.features.debug.sas.DebugSasEmojiActivity
|
||||
import im.vector.app.features.qrcode.QrCodeScannerActivity
|
||||
import org.matrix.android.sdk.internal.crypto.verification.qrcode.toQrCodeData
|
||||
import kotlinx.android.synthetic.debug.activity_debug_menu.*
|
||||
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class DebugMenuActivity : VectorBaseActivity() {
|
||||
class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() {
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_debug_menu
|
||||
override fun getBinding() = ActivityDebugMenuBinding.inflate(layoutInflater)
|
||||
|
||||
@Inject
|
||||
lateinit var activeSessionHolder: ActiveSessionHolder
|
||||
|
@ -69,17 +71,17 @@ class DebugMenuActivity : VectorBaseActivity() {
|
|||
}
|
||||
|
||||
private fun setupViews() {
|
||||
debug_test_text_view_link.setOnClickListener { testTextViewLink() }
|
||||
debug_show_sas_emoji.setOnClickListener { showSasEmoji() }
|
||||
debug_test_notification.setOnClickListener { testNotification() }
|
||||
debug_test_material_theme_light.setOnClickListener { testMaterialThemeLight() }
|
||||
debug_test_material_theme_dark.setOnClickListener { testMaterialThemeDark() }
|
||||
debug_test_crash.setOnClickListener { testCrash() }
|
||||
debug_scan_qr_code.setOnClickListener { scanQRCode() }
|
||||
views.debugTestTextViewLink.setOnClickListener { testTextViewLink() }
|
||||
views.debugShowSasEmoji.setOnClickListener { showSasEmoji() }
|
||||
views.debugTestNotification.setOnClickListener { testNotification() }
|
||||
views.debugTestMaterialThemeLight.setOnClickListener { testMaterialThemeLight() }
|
||||
views.debugTestMaterialThemeDark.setOnClickListener { testMaterialThemeDark() }
|
||||
views.debugTestCrash.setOnClickListener { testCrash() }
|
||||
views.debugScanQrCode.setOnClickListener { scanQRCode() }
|
||||
}
|
||||
|
||||
private fun renderQrCode(text: String) {
|
||||
debug_qr_code.setData(text)
|
||||
views.debugQrCode.setData(text)
|
||||
}
|
||||
|
||||
private fun testTextViewLink() {
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.view.ViewGroup
|
|||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.debug.activity_test_linkify.*
|
||||
|
||||
|
||||
class TestLinkifyActivity : AppCompatActivity() {
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import org.matrix.android.sdk.api.crypto.getAllVerificationEmojis
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||
|
||||
|
||||
class DebugSasEmojiActivity : AppCompatActivity() {
|
||||
|
||||
|
@ -30,12 +30,12 @@ class DebugSasEmojiActivity : AppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.fragment_generic_recycler)
|
||||
val controller = SasEmojiController()
|
||||
genericRecyclerView.configureWith(controller)
|
||||
views.genericRecyclerView.configureWith(controller)
|
||||
controller.setData(SasState(getAllVerificationEmojis()))
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
genericRecyclerView.cleanup()
|
||||
views.genericRecyclerView.cleanup()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import androidx.annotation.StringRes
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.dialog_confirmation_with_reason.view.*
|
||||
|
||||
|
||||
object ConfirmationDialogBuilder {
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult)
|
|||
return registerForActivityResult(ActivityResultContracts.StartActivityForResult(), onResult)
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.addFragment(
|
||||
fun VectorBaseActivity<*>.addFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
allowStateLoss: Boolean = false
|
||||
|
@ -39,7 +39,7 @@ fun VectorBaseActivity.addFragment(
|
|||
supportFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseActivity.addFragment(
|
||||
fun <T : Fragment> VectorBaseActivity<*>.addFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -51,7 +51,7 @@ fun <T : Fragment> VectorBaseActivity.addFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.replaceFragment(
|
||||
fun VectorBaseActivity<*>.replaceFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -60,7 +60,7 @@ fun VectorBaseActivity.replaceFragment(
|
|||
supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseActivity.replaceFragment(
|
||||
fun <T : Fragment> VectorBaseActivity<*>.replaceFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -72,7 +72,7 @@ fun <T : Fragment> VectorBaseActivity.replaceFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.addFragmentToBackstack(
|
||||
fun VectorBaseActivity<*>.addFragmentToBackstack(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -81,19 +81,19 @@ fun VectorBaseActivity.addFragmentToBackstack(
|
|||
supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseActivity.addFragmentToBackstack(frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false,
|
||||
option: ((FragmentTransaction) -> Unit)? = null) {
|
||||
fun <T : Fragment> VectorBaseActivity<*>.addFragmentToBackstack(frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false,
|
||||
option: ((FragmentTransaction) -> Unit)? = null) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
option?.invoke(this)
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun VectorBaseActivity.hideKeyboard() {
|
||||
fun VectorBaseActivity<*>.hideKeyboard() {
|
||||
currentFocus?.hideKeyboard()
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import androidx.activity.result.ActivityResult
|
|||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.airbnb.mvrx.BaseMvRxFragment
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.selectTxtFileToWrite
|
||||
|
@ -34,7 +35,7 @@ fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit):
|
|||
return registerForActivityResult(ActivityResultContracts.StartActivityForResult(), onResult)
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addFragment(
|
||||
fun Fragment.addFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
allowStateLoss: Boolean = false
|
||||
|
@ -42,7 +43,7 @@ fun VectorBaseFragment.addFragment(
|
|||
parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addFragment(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.addFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -54,7 +55,7 @@ fun <T : Fragment> VectorBaseFragment.addFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.replaceFragment(
|
||||
fun Fragment.replaceFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
allowStateLoss: Boolean = false
|
||||
|
@ -62,7 +63,7 @@ fun VectorBaseFragment.replaceFragment(
|
|||
parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.replaceFragment(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.replaceFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -74,7 +75,7 @@ fun <T : Fragment> VectorBaseFragment.replaceFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addFragmentToBackstack(
|
||||
fun Fragment.addFragmentToBackstack(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -83,7 +84,7 @@ fun VectorBaseFragment.addFragmentToBackstack(
|
|||
parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addFragmentToBackstack(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.addFragmentToBackstack(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -95,7 +96,7 @@ fun <T : Fragment> VectorBaseFragment.addFragmentToBackstack(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addChildFragment(
|
||||
fun Fragment.addChildFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -104,7 +105,7 @@ fun VectorBaseFragment.addChildFragment(
|
|||
childFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addChildFragment(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.addChildFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -116,7 +117,7 @@ fun <T : Fragment> VectorBaseFragment.addChildFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.replaceChildFragment(
|
||||
fun Fragment.replaceChildFragment(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -125,7 +126,7 @@ fun VectorBaseFragment.replaceChildFragment(
|
|||
childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.replaceChildFragment(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.replaceChildFragment(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
@ -137,7 +138,7 @@ fun <T : Fragment> VectorBaseFragment.replaceChildFragment(
|
|||
}
|
||||
}
|
||||
|
||||
fun VectorBaseFragment.addChildFragmentToBackstack(
|
||||
fun Fragment.addChildFragmentToBackstack(
|
||||
frameId: Int,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
|
@ -146,7 +147,7 @@ fun VectorBaseFragment.addChildFragmentToBackstack(
|
|||
childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> VectorBaseFragment.addChildFragmentToBackstack(
|
||||
fun <T : Fragment> VectorBaseFragment<*>.addChildFragmentToBackstack(
|
||||
frameId: Int,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
|
|
|
@ -25,7 +25,7 @@ import android.widget.FrameLayout
|
|||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.view_button_state.view.*
|
||||
|
||||
|
||||
class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
: FrameLayout(context, attrs, defStyle) {
|
||||
|
|
|
@ -15,23 +15,24 @@
|
|||
*/
|
||||
package im.vector.app.core.platform
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import im.vector.app.databinding.ActivityBinding
|
||||
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Simple activity with a toolbar, a waiting overlay, and a fragment container and a session.
|
||||
*/
|
||||
abstract class SimpleFragmentActivity : VectorBaseActivity() {
|
||||
abstract class SimpleFragmentActivity : VectorBaseActivity<ActivityBinding>() {
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity
|
||||
override fun getBinding() = ActivityBinding.inflate(layoutInflater)
|
||||
|
||||
@Inject lateinit var session: Session
|
||||
|
||||
|
@ -41,8 +42,8 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
|
|||
}
|
||||
|
||||
override fun initUiAndData() {
|
||||
configureToolbar(toolbar)
|
||||
waitingView = findViewById(R.id.waiting_view)
|
||||
configureToolbar(views.toolbar)
|
||||
waitingView = views.overlayWaitingView.waitingView
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,21 +52,21 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
|
|||
*/
|
||||
fun updateWaitingView(data: WaitingViewData?) {
|
||||
data?.let {
|
||||
waitingStatusText.text = data.message
|
||||
views.overlayWaitingView.waitingStatusText.text = data.message
|
||||
|
||||
if (data.progress != null && data.progressTotal != null) {
|
||||
waitingHorizontalProgress.isIndeterminate = false
|
||||
waitingHorizontalProgress.progress = data.progress
|
||||
waitingHorizontalProgress.max = data.progressTotal
|
||||
waitingHorizontalProgress.isVisible = true
|
||||
waitingCircularProgress.isVisible = false
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isIndeterminate = false
|
||||
views.overlayWaitingView.waitingHorizontalProgress.progress = data.progress
|
||||
views.overlayWaitingView.waitingHorizontalProgress.max = data.progressTotal
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isVisible = true
|
||||
views.overlayWaitingView.waitingCircularProgress.isVisible = false
|
||||
} else if (data.isIndeterminate) {
|
||||
waitingHorizontalProgress.isIndeterminate = true
|
||||
waitingHorizontalProgress.isVisible = true
|
||||
waitingCircularProgress.isVisible = false
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isIndeterminate = true
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isVisible = true
|
||||
views.overlayWaitingView.waitingCircularProgress.isVisible = false
|
||||
} else {
|
||||
waitingHorizontalProgress.isVisible = false
|
||||
waitingCircularProgress.isVisible = true
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isVisible = false
|
||||
views.overlayWaitingView.waitingCircularProgress.isVisible = true
|
||||
}
|
||||
|
||||
showWaitingView()
|
||||
|
@ -76,15 +77,15 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() {
|
|||
|
||||
override fun showWaitingView() {
|
||||
hideKeyboard()
|
||||
waitingStatusText.isGone = waitingStatusText.text.isNullOrBlank()
|
||||
views.overlayWaitingView.waitingStatusText.isGone = views.overlayWaitingView.waitingStatusText.text.isNullOrBlank()
|
||||
super.showWaitingView()
|
||||
}
|
||||
|
||||
override fun hideWaitingView() {
|
||||
waitingStatusText.text = null
|
||||
waitingStatusText.isGone = true
|
||||
waitingHorizontalProgress.progress = 0
|
||||
waitingHorizontalProgress.isVisible = false
|
||||
views.overlayWaitingView.waitingStatusText.text = null
|
||||
views.overlayWaitingView.waitingStatusText.isGone = true
|
||||
views.overlayWaitingView.waitingHorizontalProgress.progress = 0
|
||||
views.overlayWaitingView.waitingHorizontalProgress.isVisible = false
|
||||
super.hideWaitingView()
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import android.widget.FrameLayout
|
|||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.updateConstraintSet
|
||||
import kotlinx.android.synthetic.main.view_state.view.*
|
||||
|
||||
|
||||
class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0)
|
||||
: FrameLayout(context, attrs, defStyle) {
|
||||
|
|
|
@ -21,24 +21,26 @@ import android.content.Context
|
|||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.MenuRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.bumptech.glide.util.Util
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
@ -79,13 +81,19 @@ import im.vector.app.receivers.DebugReceiver
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.failure.GlobalError
|
||||
import timber.log.Timber
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
||||
abstract class VectorBaseActivity<VB: ViewBinding> : AppCompatActivity(), HasScreenInjector {
|
||||
/* ==========================================================================================
|
||||
* View
|
||||
* ========================================================================================== */
|
||||
|
||||
protected lateinit var views: VB
|
||||
|
||||
/* ==========================================================================================
|
||||
* View model
|
||||
* ========================================================================================== */
|
||||
|
@ -210,9 +218,8 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
// Hack for font size
|
||||
applyFontSize()
|
||||
|
||||
if (getLayoutRes() != -1) {
|
||||
setContentView(getLayoutRes())
|
||||
}
|
||||
views = getBinding()
|
||||
setContentView(views.root)
|
||||
|
||||
this.savedInstanceState = savedInstanceState
|
||||
|
||||
|
@ -450,7 +457,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
}
|
||||
|
||||
private fun recursivelyDispatchOnBackPressed(fm: FragmentManager, fromToolbar: Boolean): Boolean {
|
||||
val reverseOrder = fm.fragments.filterIsInstance<VectorBaseFragment>().reversed()
|
||||
val reverseOrder = fm.fragments.filterIsInstance<VectorBaseFragment<*>>().reversed()
|
||||
for (f in reverseOrder) {
|
||||
val handledByChildFragments = recursivelyDispatchOnBackPressed(f.childFragmentManager, fromToolbar)
|
||||
if (handledByChildFragments) {
|
||||
|
@ -537,8 +544,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
* OPEN METHODS
|
||||
* ========================================================================================== */
|
||||
|
||||
@LayoutRes
|
||||
open fun getLayoutRes() = -1
|
||||
abstract fun getBinding(): VB
|
||||
|
||||
open fun displayInFullscreen() = false
|
||||
|
||||
|
@ -565,13 +571,13 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
* ========================================================================================== */
|
||||
|
||||
fun showSnackbar(message: String) {
|
||||
coordinatorLayout?.let {
|
||||
getCoordinatorLayout()?.let {
|
||||
Snackbar.make(it, message, Snackbar.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
fun showSnackbar(message: String, @StringRes withActionTitle: Int?, action: (() -> Unit)?) {
|
||||
coordinatorLayout?.let {
|
||||
getCoordinatorLayout()?.let {
|
||||
Snackbar.make(it, message, Snackbar.LENGTH_LONG).apply {
|
||||
withActionTitle?.let {
|
||||
setAction(withActionTitle, { action?.invoke() })
|
||||
|
@ -580,6 +586,9 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO BMA Provide the CL from the Views
|
||||
open fun getCoordinatorLayout(): CoordinatorLayout? = null
|
||||
|
||||
/* ==========================================================================================
|
||||
* User Consent
|
||||
* ========================================================================================== */
|
||||
|
|
|
@ -27,6 +27,7 @@ import android.widget.FrameLayout
|
|||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.MvRxView
|
||||
import com.airbnb.mvrx.MvRxViewId
|
||||
|
@ -46,7 +47,7 @@ import java.util.concurrent.TimeUnit
|
|||
/**
|
||||
* Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment)
|
||||
*/
|
||||
abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MvRxView {
|
||||
abstract class VectorBaseBottomSheetDialogFragment<VB: ViewBinding> : BottomSheetDialogFragment(), MvRxView {
|
||||
|
||||
private val mvrxViewIdProperty = MvRxViewId()
|
||||
final override val mvrxViewId: String by mvrxViewIdProperty
|
||||
|
@ -56,8 +57,13 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment()
|
|||
* View
|
||||
* ========================================================================================== */
|
||||
|
||||
@LayoutRes
|
||||
abstract fun getLayoutResId(): Int
|
||||
private var _binding: VB? = null
|
||||
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
protected val views: VB
|
||||
get() = _binding!!
|
||||
|
||||
abstract fun getBinding(inflater: LayoutInflater, container: ViewGroup?): VB
|
||||
|
||||
/* ==========================================================================================
|
||||
* View model
|
||||
|
@ -77,8 +83,8 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment()
|
|||
|
||||
private var bottomSheetBehavior: BottomSheetBehavior<FrameLayout>? = null
|
||||
|
||||
val vectorBaseActivity: VectorBaseActivity by lazy {
|
||||
activity as VectorBaseActivity
|
||||
val vectorBaseActivity: VectorBaseActivity<*> by lazy {
|
||||
activity as VectorBaseActivity<*>
|
||||
}
|
||||
|
||||
open val showExpanded = false
|
||||
|
@ -102,7 +108,8 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment()
|
|||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(getLayoutResId(), container, false)
|
||||
_binding = getBinding(inflater, container)
|
||||
return views.root
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
|
|
|
@ -33,6 +33,7 @@ import androidx.annotation.MainThread
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.airbnb.mvrx.BaseMvRxFragment
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.bumptech.glide.util.Util.assertMainThread
|
||||
|
@ -48,14 +49,14 @@ import im.vector.app.features.navigation.Navigator
|
|||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
||||
abstract class VectorBaseFragment<VB: ViewBinding> : BaseMvRxFragment(), HasScreenInjector {
|
||||
|
||||
protected val vectorBaseActivity: VectorBaseActivity by lazy {
|
||||
activity as VectorBaseActivity
|
||||
protected val vectorBaseActivity: VectorBaseActivity<*> by lazy {
|
||||
activity as VectorBaseActivity<*>
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
|
@ -82,6 +83,16 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
protected val fragmentViewModelProvider
|
||||
get() = ViewModelProvider(this, viewModelFactory)
|
||||
|
||||
/* ==========================================================================================
|
||||
* Views
|
||||
* ========================================================================================== */
|
||||
|
||||
private var _binding: VB? = null
|
||||
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
protected val views: VB
|
||||
get() = _binding!!
|
||||
|
||||
/* ==========================================================================================
|
||||
* Life cycle
|
||||
* ========================================================================================== */
|
||||
|
@ -106,11 +117,11 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
|
||||
final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
Timber.i("onCreateView Fragment ${javaClass.simpleName}")
|
||||
return inflater.inflate(getLayoutResId(), container, false)
|
||||
_binding = getBinding(inflater, container)
|
||||
return views.root
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
abstract fun getLayoutResId(): Int
|
||||
abstract fun getBinding(inflater: LayoutInflater, container: ViewGroup?): VB
|
||||
|
||||
@CallSuper
|
||||
override fun onResume() {
|
||||
|
@ -137,6 +148,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
super.onDestroyView()
|
||||
Timber.i("onDestroyView Fragment ${javaClass.simpleName}")
|
||||
uiDisposables.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -174,6 +186,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
arguments = args.toMvRxBundle()
|
||||
}
|
||||
|
||||
// TODO BMA Extract this and use simple type in Fragment.kt
|
||||
fun Parcelable?.toMvRxBundle(): Bundle? {
|
||||
return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
}
|
||||
|
@ -186,7 +199,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
}
|
||||
|
||||
protected fun showErrorInSnackbar(throwable: Throwable) {
|
||||
vectorBaseActivity.coordinatorLayout?.let {
|
||||
vectorBaseActivity.getCoordinatorLayout()?.let {
|
||||
Snackbar.make(it, errorFormatter.toHumanReadable(throwable), Snackbar.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
|
|
|
@ -17,41 +17,47 @@
|
|||
package im.vector.app.core.ui.bottomsheet
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list.*
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Generic Bottom sheet with actions
|
||||
*/
|
||||
abstract class BottomSheetGeneric<STATE : BottomSheetGenericState, ACTION : BottomSheetGenericAction> :
|
||||
VectorBaseBottomSheetDialogFragment(),
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListBinding>(),
|
||||
BottomSheetGenericController.Listener<ACTION> {
|
||||
|
||||
@Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool
|
||||
|
||||
final override val showExpanded = true
|
||||
|
||||
final override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
||||
final override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding {
|
||||
return BottomSheetGenericListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
abstract fun getController(): BottomSheetGenericController<STATE, ACTION>
|
||||
|
||||
@CallSuper
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
bottomSheetRecyclerView.configureWith(getController(), viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.views.bottomSheetRecyclerView.configureWith(getController(), viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
|
||||
getController().listener = this
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.views.bottomSheetRecyclerView.cleanup()
|
||||
getController().listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
|
|
@ -29,8 +29,6 @@ import androidx.core.content.withStyledAttributes
|
|||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
@ -41,20 +39,11 @@ class BottomSheetActionButton @JvmOverloads constructor(
|
|||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
@BindView(R.id.itemVerificationActionTitle)
|
||||
lateinit var actionTextView: TextView
|
||||
|
||||
@BindView(R.id.itemVerificationActionSubTitle)
|
||||
lateinit var descriptionTextView: TextView
|
||||
|
||||
@BindView(R.id.itemVerificationLeftIcon)
|
||||
lateinit var leftIconImageView: ImageView
|
||||
|
||||
@BindView(R.id.itemVerificationActionIcon)
|
||||
lateinit var rightIconImageView: ImageView
|
||||
|
||||
@BindView(R.id.itemVerificationClickableZone)
|
||||
lateinit var clickableView: View
|
||||
private val actionTextView: TextView
|
||||
private val descriptionTextView: TextView
|
||||
private val leftIconImageView: ImageView
|
||||
private val rightIconImageView: ImageView
|
||||
private val clickableView: View
|
||||
|
||||
var title: String? = null
|
||||
set(value) {
|
||||
|
@ -116,7 +105,12 @@ class BottomSheetActionButton @JvmOverloads constructor(
|
|||
|
||||
init {
|
||||
inflate(context, R.layout.item_verification_action, this)
|
||||
ButterKnife.bind(this)
|
||||
|
||||
actionTextView = findViewById(R.id.itemVerificationActionTitle)
|
||||
descriptionTextView = findViewById(R.id.itemVerificationActionSubTitle)
|
||||
leftIconImageView = findViewById(R.id.itemVerificationLeftIcon)
|
||||
rightIconImageView = findViewById(R.id.itemVerificationActionIcon)
|
||||
clickableView = findViewById(R.id.itemVerificationClickableZone)
|
||||
|
||||
context.withStyledAttributes(attrs, R.styleable.BottomSheetActionButton) {
|
||||
title = getString(R.styleable.BottomSheetActionButton_actionTitle) ?: ""
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.view.View
|
|||
import android.widget.RelativeLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.view_jump_to_read_marker.view.*
|
||||
|
||||
|
||||
class JumpToReadMarkerView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
|
|
|
@ -24,7 +24,7 @@ import androidx.core.content.edit
|
|||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.DefaultSharedPreferences
|
||||
import kotlinx.android.synthetic.main.view_keys_backup_banner.view.*
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.error.ResourceLimitErrorFormatter
|
||||
import im.vector.app.core.utils.DimensionConverter
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
import kotlinx.android.synthetic.main.view_notification_area.view.*
|
||||
|
||||
import me.gujun.android.span.span
|
||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
||||
import org.matrix.android.sdk.api.failure.MatrixError
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.widget.LinearLayout
|
|||
import androidx.annotation.IntRange
|
||||
import androidx.core.content.ContextCompat
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.view_password_strength_bar.view.*
|
||||
|
||||
|
||||
/**
|
||||
* A password strength bar custom widget
|
||||
|
|
|
@ -26,7 +26,7 @@ import im.vector.app.R
|
|||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
|
||||
import im.vector.app.features.home.room.detail.timeline.item.toMatrixItem
|
||||
import kotlinx.android.synthetic.main.view_read_receipts.view.*
|
||||
|
||||
|
||||
private const val MAX_RECEIPT_DISPLAYED = 5
|
||||
private const val MAX_RECEIPT_DESCRIBED = 3
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.app.Activity
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -30,6 +31,7 @@ import im.vector.app.core.error.ErrorFormatter
|
|||
import im.vector.app.core.extensions.startSyncing
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.utils.deleteAllFiles
|
||||
import im.vector.app.databinding.FragmentLoadingBinding
|
||||
import im.vector.app.features.home.HomeActivity
|
||||
import im.vector.app.features.home.ShortcutsHandler
|
||||
import im.vector.app.features.login.LoginActivity
|
||||
|
@ -42,7 +44,7 @@ import im.vector.app.features.settings.VectorPreferences
|
|||
import im.vector.app.features.signout.hard.SignedOutActivity
|
||||
import im.vector.app.features.signout.soft.SoftLogoutActivity
|
||||
import im.vector.app.features.ui.UiStateRepository
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -66,7 +68,7 @@ data class MainActivityArgs(
|
|||
* This Activity, when started with argument, is also doing some cleanup when user signs out,
|
||||
* clears cache, is logged out, or is soft logged out
|
||||
*/
|
||||
class MainActivity : VectorBaseActivity(), UnlockedActivity {
|
||||
class MainActivity : VectorBaseActivity<FragmentLoadingBinding>(), UnlockedActivity {
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_ARGS = "EXTRA_ARGS"
|
||||
|
@ -83,6 +85,8 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity {
|
|||
}
|
||||
}
|
||||
|
||||
override fun getBinding() = FragmentLoadingBinding.inflate(layoutInflater)
|
||||
|
||||
private lateinit var args: MainActivityArgs
|
||||
|
||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||
|
|
|
@ -19,15 +19,17 @@ package im.vector.app.features.attachments.preview
|
|||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
import im.vector.app.features.themes.ActivityOtherThemes
|
||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||
|
||||
class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
class AttachmentsPreviewActivity : VectorBaseActivity<ActivitySimpleBinding>(), ToolbarConfigurable {
|
||||
|
||||
companion object {
|
||||
private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS"
|
||||
|
@ -51,7 +53,7 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable {
|
|||
|
||||
override fun getOtherThemes() = ActivityOtherThemes.AttachmentsPreview
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_simple
|
||||
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.app.Activity.RESULT_CANCELED
|
|||
import android.app.Activity.RESULT_OK
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
|
@ -45,9 +46,10 @@ import im.vector.app.core.resources.ColorProvider
|
|||
import im.vector.app.core.utils.OnSnapPositionChangeListener
|
||||
import im.vector.app.core.utils.SnapOnScrollListener
|
||||
import im.vector.app.core.utils.attachSnapHelperWithListener
|
||||
import im.vector.app.databinding.FragmentAttachmentsPreviewBinding
|
||||
import im.vector.app.features.media.createUCropWithDefaultSettings
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_attachments_preview.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
|
||||
import java.io.File
|
||||
|
@ -62,19 +64,21 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
private val attachmentMiniaturePreviewController: AttachmentMiniaturePreviewController,
|
||||
private val attachmentBigPreviewController: AttachmentBigPreviewController,
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment(), AttachmentMiniaturePreviewController.Callback {
|
||||
) : VectorBaseFragment<FragmentAttachmentsPreviewBinding>(), AttachmentMiniaturePreviewController.Callback {
|
||||
|
||||
private val fragmentArgs: AttachmentsPreviewArgs by args()
|
||||
private val viewModel: AttachmentsPreviewViewModel by fragmentViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_attachments_preview
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentAttachmentsPreviewBinding {
|
||||
return FragmentAttachmentsPreviewBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
applyInsets()
|
||||
setupRecyclerViews()
|
||||
setupToolbar(attachmentPreviewerToolbar)
|
||||
attachmentPreviewerSendButton.setOnClickListener {
|
||||
setupToolbar(views.attachmentPreviewerToolbar)
|
||||
views.attachmentPreviewerSendButton.setOnClickListener {
|
||||
setResultAndFinish()
|
||||
}
|
||||
}
|
||||
|
@ -120,8 +124,8 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
attachmentPreviewerMiniatureList.cleanup()
|
||||
attachmentPreviewerBigList.cleanup()
|
||||
views.attachmentPreviewerMiniatureList.cleanup()
|
||||
views.attachmentPreviewerBigList.cleanup()
|
||||
attachmentMiniaturePreviewController.callback = null
|
||||
}
|
||||
|
||||
|
@ -133,9 +137,9 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
} else {
|
||||
attachmentMiniaturePreviewController.setData(state)
|
||||
attachmentBigPreviewController.setData(state)
|
||||
attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex)
|
||||
attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex)
|
||||
attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size)
|
||||
views.attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex)
|
||||
views.attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex)
|
||||
views.attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,17 +150,17 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
private fun setResultAndFinish() = withState(viewModel) {
|
||||
(requireActivity() as? AttachmentsPreviewActivity)?.setResultAndFinish(
|
||||
it.attachments,
|
||||
attachmentPreviewerSendImageOriginalSize.isChecked
|
||||
views.attachmentPreviewerSendImageOriginalSize.isChecked
|
||||
)
|
||||
}
|
||||
|
||||
private fun applyInsets() {
|
||||
view?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
ViewCompat.setOnApplyWindowInsetsListener(attachmentPreviewerBottomContainer) { v, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerBottomContainer) { v, insets ->
|
||||
v.updatePadding(bottom = insets.systemWindowInsetBottom)
|
||||
insets
|
||||
}
|
||||
ViewCompat.setOnApplyWindowInsetsListener(attachmentPreviewerToolbar) { v, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerToolbar) { v, insets ->
|
||||
v.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = insets.systemWindowInsetTop
|
||||
}
|
||||
|
@ -180,13 +184,13 @@ class AttachmentsPreviewFragment @Inject constructor(
|
|||
private fun setupRecyclerViews() {
|
||||
attachmentMiniaturePreviewController.callback = this
|
||||
|
||||
attachmentPreviewerMiniatureList.let {
|
||||
views.attachmentPreviewerMiniatureList.let {
|
||||
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
it.setHasFixedSize(true)
|
||||
it.adapter = attachmentMiniaturePreviewController.adapter
|
||||
}
|
||||
|
||||
attachmentPreviewerBigList.let {
|
||||
views.attachmentPreviewerBigList.let {
|
||||
it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
it.attachSnapHelperWithListener(
|
||||
PagerSnapHelper(),
|
||||
|
|
|
@ -17,18 +17,24 @@
|
|||
package im.vector.app.features.call
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_call_controls.*
|
||||
import im.vector.app.databinding.BottomSheetCallControlsBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
|
||||
import me.gujun.android.span.span
|
||||
|
||||
class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_call_controls
|
||||
class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetCallControlsBinding>() {
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetCallControlsBinding {
|
||||
return BottomSheetCallControlsBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val callViewModel: VectorCallViewModel by activityViewModel()
|
||||
|
||||
|
@ -39,16 +45,16 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
renderState(it)
|
||||
}
|
||||
|
||||
callControlsSoundDevice.clickableView.debouncedClicks {
|
||||
views.callControlsSoundDevice.clickableView.debouncedClicks {
|
||||
callViewModel.handle(VectorCallViewActions.SwitchSoundDevice)
|
||||
}
|
||||
|
||||
callControlsSwitchCamera.clickableView.debouncedClicks {
|
||||
views.callControlsSwitchCamera.clickableView.debouncedClicks {
|
||||
callViewModel.handle(VectorCallViewActions.ToggleCamera)
|
||||
dismiss()
|
||||
}
|
||||
|
||||
callControlsToggleSDHD.clickableView.debouncedClicks {
|
||||
views.callControlsToggleSDHD.clickableView.debouncedClicks {
|
||||
callViewModel.handle(VectorCallViewActions.ToggleHDSD)
|
||||
dismiss()
|
||||
}
|
||||
|
@ -109,30 +115,30 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
private fun renderState(state: VectorCallViewState) {
|
||||
callControlsSoundDevice.title = getString(R.string.call_select_sound_device)
|
||||
callControlsSoundDevice.subTitle = when (state.soundDevice) {
|
||||
views.callControlsSoundDevice.title = getString(R.string.call_select_sound_device)
|
||||
views.callControlsSoundDevice.subTitle = when (state.soundDevice) {
|
||||
CallAudioManager.SoundDevice.PHONE -> getString(R.string.sound_device_phone)
|
||||
CallAudioManager.SoundDevice.SPEAKER -> getString(R.string.sound_device_speaker)
|
||||
CallAudioManager.SoundDevice.HEADSET -> getString(R.string.sound_device_headset)
|
||||
CallAudioManager.SoundDevice.WIRELESS_HEADSET -> getString(R.string.sound_device_wireless_headset)
|
||||
}
|
||||
|
||||
callControlsSwitchCamera.isVisible = state.isVideoCall && state.canSwitchCamera
|
||||
callControlsSwitchCamera.subTitle = getString(if (state.isFrontCamera) R.string.call_camera_front else R.string.call_camera_back)
|
||||
views.callControlsSwitchCamera.isVisible = state.isVideoCall && state.canSwitchCamera
|
||||
views.callControlsSwitchCamera.subTitle = getString(if (state.isFrontCamera) R.string.call_camera_front else R.string.call_camera_back)
|
||||
|
||||
if (state.isVideoCall) {
|
||||
callControlsToggleSDHD.isVisible = true
|
||||
views.callControlsToggleSDHD.isVisible = true
|
||||
if (state.isHD) {
|
||||
callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_off)
|
||||
callControlsToggleSDHD.subTitle = null
|
||||
callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd_disabled)
|
||||
views.callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_off)
|
||||
views.callControlsToggleSDHD.subTitle = null
|
||||
views.callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd_disabled)
|
||||
} else {
|
||||
callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_on)
|
||||
callControlsToggleSDHD.subTitle = null
|
||||
callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd)
|
||||
views.callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_on)
|
||||
views.callControlsToggleSDHD.subTitle = null
|
||||
views.callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd)
|
||||
}
|
||||
} else {
|
||||
callControlsToggleSDHD.isVisible = false
|
||||
views.callControlsToggleSDHD.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,13 @@ package im.vector.app.features.call
|
|||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.view_call_controls.view.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.call.CallState
|
||||
import org.webrtc.PeerConnection
|
||||
|
||||
|
@ -30,19 +32,40 @@ class CallControlsView @JvmOverloads constructor(
|
|||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
) : LinearLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private var ringingControls: View
|
||||
private var connectedControls: View
|
||||
|
||||
private val ringingControlAccept: View
|
||||
private var ringingControlDecline: View
|
||||
private var iv_end_call: View
|
||||
private var muteIcon: ImageView
|
||||
private var videoToggleIcon: ImageView
|
||||
private var iv_leftMiniControl: View
|
||||
private var iv_more: View
|
||||
|
||||
var interactionListener: InteractionListener? = null
|
||||
|
||||
init {
|
||||
ConstraintLayout.inflate(context, R.layout.view_call_controls, this)
|
||||
View.inflate(context, R.layout.view_call_controls, this)
|
||||
// layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
||||
ringingControlAccept.setOnClickListener { acceptIncomingCall() }
|
||||
ringingControlDecline.setOnClickListener { declineIncomingCall() }
|
||||
iv_end_call.setOnClickListener { endOngoingCall() }
|
||||
muteIcon.setOnClickListener { toggleMute() }
|
||||
videoToggleIcon.setOnClickListener { toggleVideo() }
|
||||
iv_leftMiniControl.setOnClickListener { returnToChat() }
|
||||
iv_more.setOnClickListener { moreControlOption() }
|
||||
ringingControlAccept = findViewById<View>(R.id.ringingControlAccept)
|
||||
.also { it.setOnClickListener { acceptIncomingCall() } }
|
||||
ringingControlDecline = findViewById<View>(R.id.ringingControlDecline)
|
||||
.also { it.setOnClickListener { declineIncomingCall() } }
|
||||
iv_end_call = findViewById<View>(R.id.iv_end_call)
|
||||
.also { it.setOnClickListener { endOngoingCall() } }
|
||||
muteIcon = findViewById<ImageView>(R.id.muteIcon)
|
||||
.also { it.setOnClickListener { toggleMute() } }
|
||||
videoToggleIcon = findViewById<ImageView>(R.id.videoToggleIcon)
|
||||
.also { it.setOnClickListener { toggleVideo() } }
|
||||
iv_leftMiniControl = findViewById<View>(R.id.iv_leftMiniControl)
|
||||
.also { it.setOnClickListener { returnToChat() } }
|
||||
iv_more = findViewById<View>(R.id.iv_more)
|
||||
.also { it.setOnClickListener { moreControlOption() } }
|
||||
|
||||
ringingControls = findViewById(R.id.ringingControls)
|
||||
connectedControls = findViewById(R.id.connectedControls)
|
||||
}
|
||||
|
||||
private fun acceptIncomingCall() {
|
||||
|
|
|
@ -23,6 +23,7 @@ import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP
|
|||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
|
@ -44,12 +45,13 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL
|
|||
import im.vector.app.core.utils.PERMISSIONS_FOR_VIDEO_IP_CALL
|
||||
import im.vector.app.core.utils.allGranted
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.databinding.ActivityCallBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.app.features.home.room.detail.RoomDetailArgs
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.activity_call.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.session.call.CallState
|
||||
import org.matrix.android.sdk.api.session.call.EglUtils
|
||||
import org.matrix.android.sdk.api.session.call.MxCallDetail
|
||||
|
@ -70,9 +72,9 @@ data class CallArgs(
|
|||
val isVideoCall: Boolean
|
||||
) : Parcelable
|
||||
|
||||
class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionListener {
|
||||
class VectorCallActivity : VectorBaseActivity<ActivityCallBinding>(), CallControlsView.InteractionListener {
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_call
|
||||
override fun getBinding() = ActivityCallBinding.inflate(layoutInflater)
|
||||
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
|
@ -147,7 +149,7 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
super.onCreate(savedInstanceState)
|
||||
|
||||
// This will need to be refined
|
||||
ViewCompat.setOnApplyWindowInsetsListener(constraintLayout) { v, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(views.constraintLayout) { v, insets ->
|
||||
v.updatePadding(bottom = if (systemUiVisibility) insets.systemWindowInsetBottom else 0)
|
||||
insets
|
||||
}
|
||||
|
@ -167,7 +169,7 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
turnScreenOnAndKeyguardOff()
|
||||
}
|
||||
|
||||
constraintLayout.clicks()
|
||||
views.constraintLayout.clicks()
|
||||
.throttleFirst(300, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe { toggleUiSystemVisibility() }
|
||||
|
@ -199,10 +201,10 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
peerConnectionManager.detachRenderers(listOf(pipRenderer, fullscreenRenderer))
|
||||
peerConnectionManager.detachRenderers(listOf(views.pipRenderer, views.fullscreenRenderer))
|
||||
if (surfaceRenderersAreInitialized) {
|
||||
pipRenderer.release()
|
||||
fullscreenRenderer.release()
|
||||
views.pipRenderer.release()
|
||||
views.fullscreenRenderer.release()
|
||||
}
|
||||
turnScreenOffAndKeyguardOn()
|
||||
super.onDestroy()
|
||||
|
@ -217,54 +219,54 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
return
|
||||
}
|
||||
|
||||
callControlsView.updateForState(state)
|
||||
views.callControlsView.updateForState(state)
|
||||
val callState = state.callState.invoke()
|
||||
callConnectingProgress.isVisible = false
|
||||
views.callConnectingProgress.isVisible = false
|
||||
when (callState) {
|
||||
is CallState.Idle,
|
||||
is CallState.Dialing -> {
|
||||
callVideoGroup.isInvisible = true
|
||||
callInfoGroup.isVisible = true
|
||||
callStatusText.setText(R.string.call_ring)
|
||||
views.callVideoGroup.isInvisible = true
|
||||
views.callInfoGroup.isVisible = true
|
||||
views.callStatusText.setText(R.string.call_ring)
|
||||
configureCallInfo(state)
|
||||
}
|
||||
|
||||
is CallState.LocalRinging -> {
|
||||
callVideoGroup.isInvisible = true
|
||||
callInfoGroup.isVisible = true
|
||||
callStatusText.text = null
|
||||
views.callVideoGroup.isInvisible = true
|
||||
views.callInfoGroup.isVisible = true
|
||||
views.callStatusText.text = null
|
||||
configureCallInfo(state)
|
||||
}
|
||||
|
||||
is CallState.Answering -> {
|
||||
callVideoGroup.isInvisible = true
|
||||
callInfoGroup.isVisible = true
|
||||
callStatusText.setText(R.string.call_connecting)
|
||||
callConnectingProgress.isVisible = true
|
||||
views.callVideoGroup.isInvisible = true
|
||||
views.callInfoGroup.isVisible = true
|
||||
views.callStatusText.setText(R.string.call_connecting)
|
||||
views.callConnectingProgress.isVisible = true
|
||||
configureCallInfo(state)
|
||||
}
|
||||
is CallState.Connected -> {
|
||||
if (callState.iceConnectionState == PeerConnection.PeerConnectionState.CONNECTED) {
|
||||
if (callArgs.isVideoCall) {
|
||||
callVideoGroup.isVisible = true
|
||||
callInfoGroup.isVisible = false
|
||||
pipRenderer.isVisible = !state.isVideoCaptureInError
|
||||
views.callVideoGroup.isVisible = true
|
||||
views.callInfoGroup.isVisible = false
|
||||
views.pipRenderer.isVisible = !state.isVideoCaptureInError
|
||||
} else {
|
||||
callVideoGroup.isInvisible = true
|
||||
callInfoGroup.isVisible = true
|
||||
views.callVideoGroup.isInvisible = true
|
||||
views.callInfoGroup.isVisible = true
|
||||
configureCallInfo(state)
|
||||
callStatusText.text = null
|
||||
views.callStatusText.text = null
|
||||
}
|
||||
} else {
|
||||
// This state is not final, if you change network, new candidates will be sent
|
||||
callVideoGroup.isInvisible = true
|
||||
callInfoGroup.isVisible = true
|
||||
views.callVideoGroup.isInvisible = true
|
||||
views.callInfoGroup.isVisible = true
|
||||
configureCallInfo(state)
|
||||
callStatusText.setText(R.string.call_connecting)
|
||||
callConnectingProgress.isVisible = true
|
||||
views.callStatusText.setText(R.string.call_connecting)
|
||||
views.callConnectingProgress.isVisible = true
|
||||
}
|
||||
// ensure all attached?
|
||||
peerConnectionManager.attachViewRenderers(pipRenderer, fullscreenRenderer, null)
|
||||
peerConnectionManager.attachViewRenderers(views.pipRenderer, views.fullscreenRenderer, null)
|
||||
}
|
||||
is CallState.Terminated -> {
|
||||
finish()
|
||||
|
@ -276,14 +278,14 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
|
||||
private fun configureCallInfo(state: VectorCallViewState) {
|
||||
state.otherUserMatrixItem.invoke()?.let {
|
||||
avatarRenderer.render(it, otherMemberAvatar)
|
||||
participantNameText.text = it.getBestName()
|
||||
callTypeText.setText(if (state.isVideoCall) R.string.action_video_call else R.string.action_voice_call)
|
||||
avatarRenderer.render(it, views.otherMemberAvatar)
|
||||
views.participantNameText.text = it.getBestName()
|
||||
views.callTypeText.setText(if (state.isVideoCall) R.string.action_video_call else R.string.action_voice_call)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureCallViews() {
|
||||
callControlsView.interactionListener = this
|
||||
views.callControlsView.interactionListener = this
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
|
@ -303,21 +305,24 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis
|
|||
}
|
||||
|
||||
// Init Picture in Picture renderer
|
||||
pipRenderer.init(rootEglBase!!.eglBaseContext, null)
|
||||
pipRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
|
||||
views.pipRenderer.init(rootEglBase!!.eglBaseContext, null)
|
||||
views.pipRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
|
||||
|
||||
// Init Full Screen renderer
|
||||
fullscreenRenderer.init(rootEglBase!!.eglBaseContext, null)
|
||||
fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
|
||||
views.fullscreenRenderer.init(rootEglBase!!.eglBaseContext, null)
|
||||
views.fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
|
||||
|
||||
pipRenderer.setZOrderMediaOverlay(true)
|
||||
pipRenderer.setEnableHardwareScaler(true /* enabled */)
|
||||
fullscreenRenderer.setEnableHardwareScaler(true /* enabled */)
|
||||
views.pipRenderer.setZOrderMediaOverlay(true)
|
||||
views.pipRenderer.setEnableHardwareScaler(true /* enabled */)
|
||||
views.fullscreenRenderer.setEnableHardwareScaler(true /* enabled */)
|
||||
|
||||
peerConnectionManager.attachViewRenderers(pipRenderer, fullscreenRenderer,
|
||||
intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() })
|
||||
peerConnectionManager.attachViewRenderers(
|
||||
views.pipRenderer,
|
||||
views.fullscreenRenderer,
|
||||
intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() }
|
||||
)
|
||||
|
||||
pipRenderer.setOnClickListener {
|
||||
views.pipRenderer.setOnClickListener {
|
||||
callViewModel.handle(VectorCallViewActions.ToggleCamera)
|
||||
}
|
||||
surfaceRenderersAreInitialized = true
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -31,8 +32,9 @@ import com.facebook.react.modules.core.PermissionListener
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.activity_jitsi.*
|
||||
import im.vector.app.databinding.ActivityJitsiBinding
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivityDelegate
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivityInterface
|
||||
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions
|
||||
|
@ -42,7 +44,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull
|
|||
import java.net.URL
|
||||
import javax.inject.Inject
|
||||
|
||||
class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, JitsiMeetViewListener {
|
||||
class VectorJitsiActivity : VectorBaseActivity<ActivityJitsiBinding>(), JitsiMeetActivityInterface, JitsiMeetViewListener {
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
|
@ -51,7 +53,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, Ji
|
|||
val enableVideo: Boolean
|
||||
) : Parcelable
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_jitsi
|
||||
override fun getBinding() = ActivityJitsiBinding.inflate(layoutInflater)
|
||||
|
||||
@Inject lateinit var viewModelFactory: JitsiCallViewModel.Factory
|
||||
|
||||
|
@ -76,7 +78,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, Ji
|
|||
super.initUiAndData()
|
||||
jitsiMeetView = JitsiMeetView(this)
|
||||
val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)
|
||||
jitsi_layout.addView(jitsiMeetView, params)
|
||||
views.jitsiLayout.addView(jitsiMeetView, params)
|
||||
jitsiMeetView?.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.contactsbook
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
|
@ -29,12 +31,14 @@ import im.vector.app.core.extensions.cleanup
|
|||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentAttachmentsPreviewBinding
|
||||
import im.vector.app.databinding.FragmentContactsBookBinding
|
||||
import im.vector.app.features.userdirectory.PendingInvitee
|
||||
import im.vector.app.features.userdirectory.UserListAction
|
||||
import im.vector.app.features.userdirectory.UserListSharedAction
|
||||
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
|
||||
import im.vector.app.features.userdirectory.UserListViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_contacts_book.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.identity.ThreePid
|
||||
import org.matrix.android.sdk.api.session.user.model.User
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -43,9 +47,12 @@ import javax.inject.Inject
|
|||
class ContactsBookFragment @Inject constructor(
|
||||
val contactsBookViewModelFactory: ContactsBookViewModel.Factory,
|
||||
private val contactsBookController: ContactsBookController
|
||||
) : VectorBaseFragment(), ContactsBookController.Callback {
|
||||
) : VectorBaseFragment<FragmentContactsBookBinding>(), ContactsBookController.Callback {
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentContactsBookBinding {
|
||||
return FragmentContactsBookBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_contacts_book
|
||||
private val viewModel: UserListViewModel by activityViewModel()
|
||||
|
||||
// Use activityViewModel to avoid loading several times the data
|
||||
|
@ -64,7 +71,7 @@ class ContactsBookFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun setupConsentView() {
|
||||
phoneBookSearchForMatrixContacts.setOnClickListener {
|
||||
views.phoneBookSearchForMatrixContacts.setOnClickListener {
|
||||
withState(contactsBookViewModel) { state ->
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(R.string.identity_server_consent_dialog_title)
|
||||
|
@ -79,7 +86,7 @@ class ContactsBookFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun setupOnlyBoundContactsView() {
|
||||
phoneBookOnlyBoundContacts.checkedChanges()
|
||||
views.phoneBookOnlyBoundContacts.checkedChanges()
|
||||
.subscribe {
|
||||
contactsBookViewModel.handle(ContactsBookAction.OnlyBoundContacts(it))
|
||||
}
|
||||
|
@ -87,7 +94,7 @@ class ContactsBookFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun setupFilterView() {
|
||||
phoneBookFilter
|
||||
views.phoneBookFilter
|
||||
.textChanges()
|
||||
.skipInitialValue()
|
||||
.debounce(300, TimeUnit.MILLISECONDS)
|
||||
|
@ -98,25 +105,25 @@ class ContactsBookFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
phoneBookRecyclerView.cleanup()
|
||||
views.phoneBookRecyclerView.cleanup()
|
||||
contactsBookController.callback = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
contactsBookController.callback = this
|
||||
phoneBookRecyclerView.configureWith(contactsBookController)
|
||||
views.phoneBookRecyclerView.configureWith(contactsBookController)
|
||||
}
|
||||
|
||||
private fun setupCloseView() {
|
||||
phoneBookClose.debouncedClicks {
|
||||
views.phoneBookClose.debouncedClicks {
|
||||
sharedActionViewModel.post(UserListSharedAction.GoBack)
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(contactsBookViewModel) { state ->
|
||||
phoneBookSearchForMatrixContacts.isVisible = state.filteredMappedContacts.isNotEmpty() && state.identityServerUrl != null && !state.userConsent
|
||||
phoneBookOnlyBoundContacts.isVisible = state.isBoundRetrieved
|
||||
views.phoneBookSearchForMatrixContacts.isVisible = state.filteredMappedContacts.isNotEmpty() && state.identityServerUrl != null && !state.userConsent
|
||||
views.phoneBookOnlyBoundContacts.isVisible = state.isBoundRetrieved
|
||||
contactsBookController.setData(state)
|
||||
}
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ import im.vector.app.features.userdirectory.UserListSharedAction
|
|||
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
|
||||
import im.vector.app.features.userdirectory.UserListViewModel
|
||||
import im.vector.app.features.userdirectory.UserListViewState
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure
|
||||
import java.net.HttpURLConnection
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package im.vector.app.features.createdirect
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import com.google.zxing.Result
|
||||
|
@ -26,19 +28,23 @@ import im.vector.app.core.platform.VectorBaseFragment
|
|||
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.FragmentAttachmentsPreviewBinding
|
||||
import im.vector.app.databinding.FragmentQrCodeScannerBinding
|
||||
import im.vector.app.features.userdirectory.PendingInvitee
|
||||
import kotlinx.android.synthetic.main.fragment_qr_code_scanner.*
|
||||
|
||||
import me.dm7.barcodescanner.zxing.ZXingScannerView
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
|
||||
import org.matrix.android.sdk.api.session.user.model.User
|
||||
import javax.inject.Inject
|
||||
|
||||
class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler {
|
||||
class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragment<FragmentQrCodeScannerBinding>(), ZXingScannerView.ResultHandler {
|
||||
|
||||
private val viewModel: CreateDirectRoomViewModel by activityViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_qr_code_scanner
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerBinding {
|
||||
return FragmentQrCodeScannerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted ->
|
||||
if (allGranted) {
|
||||
|
@ -48,14 +54,14 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen
|
|||
|
||||
private fun startCamera() {
|
||||
// Start camera on resume
|
||||
scannerView.startCamera()
|
||||
views.scannerView.startCamera()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
view?.hideKeyboard()
|
||||
// Register ourselves as a handler for scan results.
|
||||
scannerView.setResultHandler(this)
|
||||
views.scannerView.setResultHandler(this)
|
||||
// Start camera on resume
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), openCameraActivityResultLauncher)) {
|
||||
startCamera()
|
||||
|
@ -65,9 +71,9 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen
|
|||
override fun onPause() {
|
||||
super.onPause()
|
||||
// Unregister ourselves as a handler for scan results.
|
||||
scannerView.setResultHandler(null)
|
||||
views.scannerView.setResultHandler(null)
|
||||
// Stop camera on pause
|
||||
scannerView.stopCamera()
|
||||
views.scannerView.stopCamera()
|
||||
}
|
||||
|
||||
// Copied from https://github.com/markusfisch/BinaryEye/blob/
|
||||
|
|
|
@ -17,7 +17,9 @@ package im.vector.app.features.crypto.keysbackup.restore
|
|||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.Observer
|
||||
|
@ -25,14 +27,18 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.startImportTextFromFileIntent
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_restore_from_key.*
|
||||
import im.vector.app.databinding.FragmentAttachmentsPreviewBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreFromKeyFragment @Inject constructor()
|
||||
: VectorBaseFragment() {
|
||||
: VectorBaseFragment<FragmentKeysBackupRestoreFromKeyBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_key
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreFromKeyBinding {
|
||||
return FragmentKeysBackupRestoreFromKeyBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private lateinit var viewModel: KeysBackupRestoreFromKeyViewModel
|
||||
private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel
|
||||
|
@ -41,8 +47,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor()
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
viewModel = fragmentViewModelProvider.get(KeysBackupRestoreFromKeyViewModel::class.java)
|
||||
sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java)
|
||||
mKeyTextEdit.setText(viewModel.recoveryCode.value)
|
||||
mKeyTextEdit.setOnEditorActionListener { _, actionId, _ ->
|
||||
views.mKeyTextEdit.setText(viewModel.recoveryCode.value)
|
||||
views.mKeyTextEdit.setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
onRestoreFromKey()
|
||||
return@setOnEditorActionListener true
|
||||
|
@ -50,14 +56,14 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor()
|
|||
return@setOnEditorActionListener false
|
||||
}
|
||||
|
||||
mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value
|
||||
views.mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value
|
||||
viewModel.recoveryCodeErrorText.observe(viewLifecycleOwner, Observer { newValue ->
|
||||
mKeyInputLayout.error = newValue
|
||||
views.mKeyInputLayout.error = newValue
|
||||
})
|
||||
|
||||
keys_restore_button.setOnClickListener { onRestoreFromKey() }
|
||||
keys_backup_import.setOnClickListener { onImport() }
|
||||
mKeyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) }
|
||||
views.keysRestoreButton.setOnClickListener { onRestoreFromKey() }
|
||||
views.keysBackupImport.setOnClickListener { onImport() }
|
||||
views.mKeyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) }
|
||||
}
|
||||
|
||||
private fun onRestoreKeyTextEditChange(s: CharSequence?) {
|
||||
|
@ -89,8 +95,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor()
|
|||
?.bufferedReader()
|
||||
?.use { it.readText() }
|
||||
?.let {
|
||||
mKeyTextEdit.setText(it)
|
||||
mKeyTextEdit.setSelection(it.length)
|
||||
views.mKeyTextEdit.setText(it)
|
||||
views.mKeyTextEdit.setSelection(it.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.crypto.keysbackup.restore
|
|||
import android.os.Bundle
|
||||
import android.text.SpannableString
|
||||
import android.text.style.ClickableSpan
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.text.set
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
|
@ -26,12 +28,16 @@ import androidx.lifecycle.Observer
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.showPassword
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_restore_from_passphrase.*
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromPassphraseBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment<FragmentKeysBackupRestoreFromPassphraseBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_passphrase
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreFromPassphraseBinding {
|
||||
return FragmentKeysBackupRestoreFromPassphraseBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private lateinit var viewModel: KeysBackupRestoreFromPassphraseViewModel
|
||||
private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel
|
||||
|
@ -47,18 +53,18 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
|
|||
sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java)
|
||||
|
||||
viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue ->
|
||||
keys_backup_passphrase_enter_til.error = newValue
|
||||
views.keysBackupPassphraseEnterTil.error = newValue
|
||||
})
|
||||
|
||||
helperTextWithLink.text = spannableStringForHelperText()
|
||||
views.helperTextWithLink.text = spannableStringForHelperText()
|
||||
|
||||
viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer {
|
||||
val shouldBeVisible = it ?: false
|
||||
keys_backup_passphrase_enter_edittext.showPassword(shouldBeVisible)
|
||||
keys_backup_view_show_password.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
views.keysBackupPassphraseEnterEdittext.showPassword(shouldBeVisible)
|
||||
views.keysBackupViewShowPassword.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
})
|
||||
|
||||
keys_backup_passphrase_enter_edittext.setOnEditorActionListener { _, actionId, _ ->
|
||||
views.keysBackupPassphraseEnterEdittext.setOnEditorActionListener { _, actionId, _ ->
|
||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
onRestoreBackup()
|
||||
return@setOnEditorActionListener true
|
||||
|
@ -66,10 +72,10 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase
|
|||
return@setOnEditorActionListener false
|
||||
}
|
||||
|
||||
keys_backup_view_show_password.setOnClickListener { toggleVisibilityMode() }
|
||||
helperTextWithLink.setOnClickListener { onUseRecoveryKey() }
|
||||
keys_backup_restore_with_passphrase_submit.setOnClickListener { onRestoreBackup() }
|
||||
keys_backup_passphrase_enter_edittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) }
|
||||
views.keysBackupViewShowPassword.setOnClickListener { toggleVisibilityMode() }
|
||||
views.helperTextWithLink.setOnClickListener { onUseRecoveryKey() }
|
||||
views.keysBackupRestoreWithPassphraseSubmit.setOnClickListener { onRestoreBackup() }
|
||||
views.keysBackupPassphraseEnterEdittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) }
|
||||
}
|
||||
|
||||
private fun spannableStringForHelperText(): SpannableString {
|
||||
|
|
|
@ -16,17 +16,23 @@
|
|||
package im.vector.app.features.crypto.keysbackup.restore
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.LiveEvent
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_restore_success.*
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreSuccessBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment<FragmentKeysBackupRestoreSuccessBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_success
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreSuccessBinding {
|
||||
return FragmentKeysBackupRestoreSuccessBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel
|
||||
|
||||
|
@ -40,15 +46,15 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen
|
|||
it.totalNumberOfKeys, it.totalNumberOfKeys)
|
||||
val part2 = resources.getQuantityString(R.plurals.keys_backup_restore_success_description_part2,
|
||||
it.successfullyNumberOfImportedKeys, it.successfullyNumberOfImportedKeys)
|
||||
mSuccessDetailsText.text = String.format("%s\n%s", part1, part2)
|
||||
views.mSuccessDetailsText.text = String.format("%s\n%s", part1, part2)
|
||||
}
|
||||
// We don't put emoji in string xml as it will crash on old devices
|
||||
mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title, "🎉")
|
||||
views.mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title, "🎉")
|
||||
} else {
|
||||
mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date)
|
||||
mSuccessDetailsText.isVisible = false
|
||||
views.mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date)
|
||||
views.mSuccessDetailsText.isVisible = false
|
||||
}
|
||||
keys_backup_setup_done_button.setOnClickListener { onDone() }
|
||||
views.keysBackupSetupDoneButton.setOnClickListener { onDone() }
|
||||
}
|
||||
|
||||
private fun onDone() {
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package im.vector.app.features.crypto.keysbackup.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -24,28 +26,32 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupSettingsBinding
|
||||
import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity
|
||||
import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_settings.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController)
|
||||
: VectorBaseFragment(),
|
||||
: VectorBaseFragment<FragmentKeysBackupSettingsBinding>(),
|
||||
KeysBackupSettingsRecyclerViewController.Listener {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_settings
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSettingsBinding {
|
||||
return FragmentKeysBackupSettingsBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val viewModel: KeysBackupSettingsViewModel by activityViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
keysBackupSettingsRecyclerView.configureWith(keysBackupSettingsRecyclerViewController)
|
||||
views.keysBackupSettingsRecyclerView.configureWith(keysBackupSettingsRecyclerViewController)
|
||||
keysBackupSettingsRecyclerViewController.listener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
keysBackupSettingsRecyclerViewController.listener = null
|
||||
keysBackupSettingsRecyclerView.cleanup()
|
||||
views.keysBackupSettingsRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
|
|
|
@ -17,17 +17,23 @@
|
|||
package im.vector.app.features.crypto.keysbackup.setup
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.lifecycle.Observer
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.LiveEvent
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step1.*
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupSetupStep1Binding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment<FragmentKeysBackupSetupStep1Binding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step1
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSetupStep1Binding {
|
||||
return FragmentKeysBackupSetupStep1Binding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private lateinit var viewModel: KeysBackupSetupSharedViewModel
|
||||
|
||||
|
@ -39,12 +45,12 @@ class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment()
|
|||
viewModel.showManualExport.observe(viewLifecycleOwner, Observer {
|
||||
val showOption = it ?: false
|
||||
// Can't use isVisible because the kotlin compiler will crash with Back-end (JVM) Internal error: wrong code generated
|
||||
advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE
|
||||
manualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE
|
||||
views.advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE
|
||||
views.manualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE
|
||||
})
|
||||
|
||||
keys_backup_setup_step1_button.setOnClickListener { onButtonClick() }
|
||||
manualExportButton.setOnClickListener { onManualExportClick() }
|
||||
views.keysBackupSetupStep1Button.setOnClickListener { onButtonClick() }
|
||||
views.manualExportButton.setOnClickListener { onManualExportClick() }
|
||||
}
|
||||
|
||||
private fun onButtonClick() {
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package im.vector.app.features.crypto.keysbackup.setup
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.widget.doOnTextChanged
|
||||
import androidx.lifecycle.Observer
|
||||
|
@ -26,15 +28,19 @@ import com.nulabinc.zxcvbn.Zxcvbn
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.showPassword
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupSetupStep2Binding
|
||||
import im.vector.app.features.settings.VectorLocale
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step2.*
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment<FragmentKeysBackupSetupStep2Binding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step2
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSetupStep2Binding {
|
||||
return FragmentKeysBackupSetupStep2Binding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val zxcvbn = Zxcvbn()
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.crypto.keysbackup.setup
|
|||
import android.app.Activity
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
|
@ -33,7 +35,9 @@ import im.vector.app.core.utils.LiveEvent
|
|||
import im.vector.app.core.utils.copyToClipboard
|
||||
import im.vector.app.core.utils.selectTxtFileToWrite
|
||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||
import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step3.*
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupSetupStep3Binding
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -44,9 +48,11 @@ import java.util.Date
|
|||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() {
|
||||
class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment<FragmentKeysBackupSetupStep3Binding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step3
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSetupStep3Binding {
|
||||
return FragmentKeysBackupSetupStep3Binding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private lateinit var viewModel: KeysBackupSetupSharedViewModel
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ import im.vector.app.core.extensions.commitTransaction
|
|||
import im.vector.app.core.platform.SimpleFragmentActivity
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.features.crypto.recover.SetupMode
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.crypto.quads
|
|||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import com.jakewharton.rxbinding3.widget.editorActionEvents
|
||||
|
@ -27,15 +29,19 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.startImportTextFromFileIntent
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentSsssAccessFromKeyBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_ssss_access_from_key.*
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment<FragmentSsssAccessFromKeyBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_ssss_access_from_key
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssAccessFromKeyBinding {
|
||||
return FragmentSsssAccessFromKeyBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: SharedSecureStorageViewModel by activityViewModel()
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.crypto.quads
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.text.toSpannable
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
|
@ -29,16 +31,20 @@ import im.vector.app.core.extensions.showPassword
|
|||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentSsssAccessFromPassphraseBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_ssss_access_from_passphrase.*
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class SharedSecuredStoragePassphraseFragment @Inject constructor(
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentSsssAccessFromPassphraseBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_ssss_access_from_passphrase
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssAccessFromPassphraseBinding {
|
||||
return FragmentSsssAccessFromPassphraseBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: SharedSecureStorageViewModel by activityViewModel()
|
||||
|
||||
|
@ -48,7 +54,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor(
|
|||
// If has passphrase
|
||||
val pass = getString(R.string.recovery_passphrase)
|
||||
val key = getString(R.string.recovery_key)
|
||||
ssss_restore_with_passphrase_warning_text.text = getString(
|
||||
views.ssssRestoreWithPassphraseWarningText.text = getString(
|
||||
R.string.enter_secret_storage_passphrase_or_key,
|
||||
pass,
|
||||
key
|
||||
|
@ -57,7 +63,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor(
|
|||
.colorizeMatchingText(pass, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
||||
.colorizeMatchingText(key, colorProvider.getColorFromAttribute(android.R.attr.textColorLink))
|
||||
|
||||
ssss_passphrase_enter_edittext.editorActionEvents()
|
||||
views.ssssPassphraseEnterEdittext.editorActionEvents()
|
||||
.throttleFirst(300, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
|
@ -67,40 +73,40 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor(
|
|||
}
|
||||
.disposeOnDestroyView()
|
||||
|
||||
ssss_passphrase_enter_edittext.textChanges()
|
||||
views.ssssPassphraseEnterEdittext.textChanges()
|
||||
.subscribe {
|
||||
ssss_passphrase_enter_til.error = null
|
||||
ssss_passphrase_submit.isEnabled = it.isNotBlank()
|
||||
views.ssssPassphraseEnterTil.error = null
|
||||
views.ssssPassphraseSubmit.isEnabled = it.isNotBlank()
|
||||
}
|
||||
.disposeOnDestroyView()
|
||||
|
||||
ssss_passphrase_reset.clickableView.debouncedClicks {
|
||||
views.ssssPassphraseReset.clickableView.debouncedClicks {
|
||||
sharedViewModel.handle(SharedSecureStorageAction.ForgotResetAll)
|
||||
}
|
||||
|
||||
sharedViewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is SharedSecureStorageViewEvent.InlineError -> {
|
||||
ssss_passphrase_enter_til.error = it.message
|
||||
views.ssssPassphraseEnterTil.error = it.message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssss_passphrase_submit.debouncedClicks { submit() }
|
||||
ssss_passphrase_use_key.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.UseKey) }
|
||||
ssss_view_show_password.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.TogglePasswordVisibility) }
|
||||
views.ssssPassphraseSubmit.debouncedClicks { submit() }
|
||||
views.ssssPassphraseUseKey.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.UseKey) }
|
||||
views.ssssViewShowPassword.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.TogglePasswordVisibility) }
|
||||
}
|
||||
|
||||
fun submit() {
|
||||
val text = ssss_passphrase_enter_edittext.text.toString()
|
||||
val text = views.ssssPassphraseEnterEdittext.text.toString()
|
||||
if (text.isBlank()) return // Should not reach this point as button disabled
|
||||
ssss_passphrase_submit.isEnabled = false
|
||||
views.ssssPassphraseSubmit.isEnabled = false
|
||||
sharedViewModel.handle(SharedSecureStorageAction.SubmitPassphrase(text))
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
val shouldBeVisible = state.passphraseVisible
|
||||
ssss_passphrase_enter_edittext.showPassword(shouldBeVisible)
|
||||
ssss_view_show_password.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
views.ssssPassphraseEnterEdittext.showPassword(shouldBeVisible)
|
||||
views.ssssViewShowPassword.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,41 +17,48 @@
|
|||
package im.vector.app.features.crypto.quads
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentSsssResetAllBinding
|
||||
import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet
|
||||
import kotlinx.android.synthetic.main.fragment_ssss_reset_all.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class SharedSecuredStorageResetAllFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class SharedSecuredStorageResetAllFragment @Inject constructor()
|
||||
: VectorBaseFragment<FragmentSsssResetAllBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_ssss_reset_all
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssResetAllBinding {
|
||||
return FragmentSsssResetAllBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: SharedSecureStorageViewModel by activityViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
ssss_reset_button_reset.debouncedClicks {
|
||||
views.ssssResetButtonReset.debouncedClicks {
|
||||
sharedViewModel.handle(SharedSecureStorageAction.DoResetAll)
|
||||
}
|
||||
|
||||
ssss_reset_button_cancel.debouncedClicks {
|
||||
views.ssssResetButtonCancel.debouncedClicks {
|
||||
sharedViewModel.handle(SharedSecureStorageAction.Back)
|
||||
}
|
||||
|
||||
ssss_reset_other_devices.debouncedClicks {
|
||||
views.ssssResetOtherDevices.debouncedClicks {
|
||||
withState(sharedViewModel) {
|
||||
DeviceListBottomSheet.newInstance(it.userId, false).show(childFragmentManager, "DEV_LIST")
|
||||
}
|
||||
}
|
||||
|
||||
sharedViewModel.subscribe(this) { state ->
|
||||
ssss_reset_other_devices.setTextOrHide(
|
||||
views.ssssResetOtherDevices.setTextOrHide(
|
||||
state.activeDeviceCount
|
||||
.takeIf { it > 0 }
|
||||
?.let { resources.getQuantityString(R.plurals.secure_backup_reset_devices_you_can_verify, it, it) }
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.text.toSpannable
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
|
@ -30,18 +32,22 @@ import im.vector.app.core.extensions.showPassword
|
|||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
import im.vector.app.databinding.FragmentBootstrapEnterAccountPasswordBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_account_password.*
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.bootstrapDescriptionText
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.ssss_view_show_password
|
||||
|
||||
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapAccountPasswordFragment @Inject constructor(
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentBootstrapEnterAccountPasswordBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_account_password
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterAccountPasswordBinding {
|
||||
return FragmentBootstrapEnterAccountPasswordBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
|
|
|
@ -36,12 +36,14 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_bootstrap.*
|
||||
import im.vector.app.databinding.BottomSheetBootstrapBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetBootstrapBinding>() {
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
|
@ -59,7 +61,9 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_bootstrap
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetBootstrapBinding {
|
||||
return BottomSheetBootstrapBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -120,60 +124,60 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
override fun invalidate() = withState(viewModel) { state ->
|
||||
when (state.step) {
|
||||
is BootstrapStep.CheckingMigration -> {
|
||||
bootstrapIcon.isVisible = false
|
||||
bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title)
|
||||
views.bootstrapIcon.isVisible = false
|
||||
views.bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title)
|
||||
showFragment(BootstrapWaitingFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.FirstForm -> {
|
||||
bootstrapIcon.isVisible = false
|
||||
bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title)
|
||||
views.bootstrapIcon.isVisible = false
|
||||
views.bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title)
|
||||
showFragment(BootstrapSetupRecoveryKeyFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.SetupPassphrase -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp))
|
||||
bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp))
|
||||
views.bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title)
|
||||
showFragment(BootstrapEnterPassphraseFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.ConfirmPassphrase -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp))
|
||||
bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp))
|
||||
views.bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title)
|
||||
showFragment(BootstrapConfirmPassphraseFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.AccountPassword -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user))
|
||||
bootstrapTitleText.text = getString(R.string.account_password)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user))
|
||||
views.bootstrapTitleText.text = getString(R.string.account_password)
|
||||
showFragment(BootstrapAccountPasswordFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.Initializing -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
bootstrapTitleText.text = getString(R.string.bootstrap_loading_title)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
views.bootstrapTitleText.text = getString(R.string.bootstrap_loading_title)
|
||||
showFragment(BootstrapWaitingFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.SaveRecoveryKey -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
bootstrapTitleText.text = getString(R.string.bottom_sheet_save_your_recovery_key_title)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
views.bootstrapTitleText.text = getString(R.string.bottom_sheet_save_your_recovery_key_title)
|
||||
showFragment(BootstrapSaveRecoveryKeyFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.DoneSuccess -> {
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
bootstrapTitleText.text = getString(R.string.bootstrap_finish_title)
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp))
|
||||
views.bootstrapTitleText.text = getString(R.string.bootstrap_finish_title)
|
||||
showFragment(BootstrapConclusionFragment::class, Bundle())
|
||||
}
|
||||
is BootstrapStep.GetBackupSecretForMigration -> {
|
||||
val isKey = state.step.useKey()
|
||||
val drawableRes = if (isKey) R.drawable.ic_security_key_24dp else R.drawable.ic_security_phrase_24dp
|
||||
bootstrapIcon.isVisible = true
|
||||
bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(
|
||||
views.bootstrapIcon.isVisible = true
|
||||
views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(
|
||||
requireContext(),
|
||||
drawableRes)
|
||||
)
|
||||
bootstrapTitleText.text = getString(R.string.upgrade_security)
|
||||
views.bootstrapTitleText.text = getString(R.string.upgrade_security)
|
||||
showFragment(BootstrapMigrateBackupFragment::class, Bundle())
|
||||
}
|
||||
}.exhaustive
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.toSpannable
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -25,27 +27,31 @@ import im.vector.app.R
|
|||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_conclusion.*
|
||||
import im.vector.app.databinding.FragmentBootstrapConclusionBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapConclusionFragment @Inject constructor(
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentBootstrapConclusionBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_conclusion
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapConclusionBinding {
|
||||
return FragmentBootstrapConclusionBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
bootstrapConclusionContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Completed) }
|
||||
views.bootstrapConclusionContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Completed) }
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
if (state.step !is BootstrapStep.DoneSuccess) return@withState
|
||||
|
||||
bootstrapConclusionText.text = getString(
|
||||
views.bootstrapConclusionText.text = getString(
|
||||
R.string.bootstrap_cross_signing_success,
|
||||
getString(R.string.recovery_passphrase),
|
||||
getString(R.string.message_key)
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.view.isGone
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
|
@ -28,14 +30,19 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.extensions.showPassword
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.*
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapConfirmPassphraseFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class BootstrapConfirmPassphraseFragment @Inject constructor()
|
||||
: VectorBaseFragment<FragmentBootstrapEnterPassphraseBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_passphrase
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterPassphraseBinding {
|
||||
return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -26,29 +28,34 @@ import com.jakewharton.rxbinding3.widget.textChanges
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.showPassword
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.features.settings.VectorLocale
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.*
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class BootstrapEnterPassphraseFragment @Inject constructor()
|
||||
: VectorBaseFragment<FragmentBootstrapEnterPassphraseBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_passphrase
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterPassphraseBinding {
|
||||
return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
bootstrapDescriptionText.text = getString(R.string.set_a_security_phrase_notice)
|
||||
ssss_passphrase_enter_edittext.hint = getString(R.string.set_a_security_phrase_hint)
|
||||
views.bootstrapDescriptionText.text = getString(R.string.set_a_security_phrase_notice)
|
||||
views.ssssPassphraseEnterEdittext.hint = getString(R.string.set_a_security_phrase_hint)
|
||||
|
||||
withState(sharedViewModel) {
|
||||
// set initial value (useful when coming back)
|
||||
ssss_passphrase_enter_edittext.setText(it.passphrase ?: "")
|
||||
views.ssssPassphraseEnterEdittext.setText(it.passphrase ?: "")
|
||||
}
|
||||
ssss_passphrase_enter_edittext.editorActionEvents()
|
||||
views.ssssPassphraseEnterEdittext.editorActionEvents()
|
||||
.throttleFirst(300, TimeUnit.MILLISECONDS)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe {
|
||||
|
@ -58,7 +65,7 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen
|
|||
}
|
||||
.disposeOnDestroyView()
|
||||
|
||||
ssss_passphrase_enter_edittext.textChanges()
|
||||
views.ssssPassphraseEnterEdittext.textChanges()
|
||||
.subscribe {
|
||||
// ssss_passphrase_enter_til.error = null
|
||||
sharedViewModel.handle(BootstrapActions.UpdateCandidatePassphrase(it?.toString() ?: ""))
|
||||
|
@ -74,8 +81,8 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen
|
|||
// }
|
||||
}
|
||||
|
||||
ssss_view_show_password.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) }
|
||||
bootstrapSubmit.debouncedClicks { submit() }
|
||||
views.ssssViewShowPassword.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) }
|
||||
views.bootstrapSubmit.debouncedClicks { submit() }
|
||||
}
|
||||
|
||||
private fun submit() = withState(sharedViewModel) { state ->
|
||||
|
@ -83,11 +90,11 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen
|
|||
return@withState
|
||||
}
|
||||
val score = state.passphraseStrength.invoke()?.score
|
||||
val passphrase = ssss_passphrase_enter_edittext.text?.toString()
|
||||
val passphrase = views.ssssPassphraseEnterEdittext.text?.toString()
|
||||
if (passphrase.isNullOrBlank()) {
|
||||
ssss_passphrase_enter_til.error = getString(R.string.passphrase_empty_error_message)
|
||||
views.ssssPassphraseEnterTil.error = getString(R.string.passphrase_empty_error_message)
|
||||
} else if (score != 4) {
|
||||
ssss_passphrase_enter_til.error = getString(R.string.passphrase_passphrase_too_weak)
|
||||
views.ssssPassphraseEnterTil.error = getString(R.string.passphrase_passphrase_too_weak)
|
||||
} else {
|
||||
sharedViewModel.handle(BootstrapActions.GoToConfirmPassphrase(passphrase))
|
||||
}
|
||||
|
@ -96,21 +103,21 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen
|
|||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
if (state.step is BootstrapStep.SetupPassphrase) {
|
||||
val isPasswordVisible = state.step.isPasswordVisible
|
||||
ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false)
|
||||
ssss_view_show_password.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
views.ssssPassphraseEnterEdittext.showPassword(isPasswordVisible, updateCursor = false)
|
||||
views.ssssViewShowPassword.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye)
|
||||
|
||||
state.passphraseStrength.invoke()?.let { strength ->
|
||||
val score = strength.score
|
||||
ssss_passphrase_security_progress.strength = score
|
||||
views.ssssPassphraseSecurityProgress.strength = score
|
||||
if (score in 1..3) {
|
||||
val hint =
|
||||
strength.feedback?.getWarning(VectorLocale.applicationLocale)?.takeIf { it.isNotBlank() }
|
||||
?: strength.feedback?.getSuggestions(VectorLocale.applicationLocale)?.firstOrNull()
|
||||
if (hint != null && hint != ssss_passphrase_enter_til.error.toString()) {
|
||||
ssss_passphrase_enter_til.error = hint
|
||||
if (hint != null && hint != views.ssssPassphraseEnterTil.error.toString()) {
|
||||
views.ssssPassphraseEnterTil.error = hint
|
||||
}
|
||||
} else {
|
||||
ssss_passphrase_enter_til.error = null
|
||||
views.ssssPassphraseEnterTil.error = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ import android.os.Bundle
|
|||
import android.text.InputType.TYPE_CLASS_TEXT
|
||||
import android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE
|
||||
import android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.core.text.toSpannable
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -37,9 +39,11 @@ import im.vector.app.core.platform.VectorBaseFragment
|
|||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
import im.vector.app.core.utils.startImportTextFromFileIntent
|
||||
import im.vector.app.databinding.FragmentBootstrapMigrateBackupBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.bootstrapDescriptionText
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_migrate_backup.*
|
||||
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.internal.crypto.keysbackup.util.isValidRecoveryKey
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -47,9 +51,11 @@ import javax.inject.Inject
|
|||
|
||||
class BootstrapMigrateBackupFragment @Inject constructor(
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentBootstrapMigrateBackupBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_migrate_backup
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapMigrateBackupBinding {
|
||||
return FragmentBootstrapMigrateBackupBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@ import android.app.Activity
|
|||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -30,7 +32,9 @@ import im.vector.app.core.platform.VectorBaseFragment
|
|||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||
import im.vector.app.core.utils.toast
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_save_key.*
|
||||
import im.vector.app.databinding.FragmentBootstrapSaveKeyBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -38,18 +42,20 @@ import javax.inject.Inject
|
|||
|
||||
class BootstrapSaveRecoveryKeyFragment @Inject constructor(
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentBootstrapSaveKeyBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_save_key
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapSaveKeyBinding {
|
||||
return FragmentBootstrapSaveKeyBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() }
|
||||
recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() }
|
||||
recoveryContinue.clickableView.debouncedClicks {
|
||||
views.recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() }
|
||||
views.recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() }
|
||||
views.recoveryContinue.clickableView.debouncedClicks {
|
||||
// We do not display the final Fragment anymore
|
||||
// TODO Do some cleanup
|
||||
// sharedViewModel.handle(BootstrapActions.GoToCompleted)
|
||||
|
@ -112,7 +118,7 @@ class BootstrapSaveRecoveryKeyFragment @Inject constructor(
|
|||
val step = state.step
|
||||
if (step !is BootstrapStep.SaveRecoveryKey) return@withState
|
||||
|
||||
recoveryContinue.isVisible = step.isSaved
|
||||
bootstrapRecoveryKeyText.text = state.recoveryKeyCreationInfo?.recoveryKey?.formatRecoveryKey()
|
||||
views.recoveryContinue.isVisible = step.isSaved
|
||||
views.bootstrapRecoveryKeyText.text = state.recoveryKeyCreationInfo?.recoveryKey?.formatRecoveryKey()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,18 +17,25 @@
|
|||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_setup_recovery.*
|
||||
import im.vector.app.databinding.FragmentBootstrapSetupRecoveryBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class BootstrapSetupRecoveryKeyFragment @Inject constructor()
|
||||
: VectorBaseFragment<FragmentBootstrapSetupRecoveryBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_setup_recovery
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapSetupRecoveryBinding {
|
||||
return FragmentBootstrapSetupRecoveryBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
|
@ -36,15 +43,15 @@ class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragme
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// Actions when a key backup exist
|
||||
bootstrapSetupSecureSubmit.clickableView.debouncedClicks {
|
||||
views.bootstrapSetupSecureSubmit.clickableView.debouncedClicks {
|
||||
sharedViewModel.handle(BootstrapActions.StartKeyBackupMigration)
|
||||
}
|
||||
|
||||
// Actions when there is no key backup
|
||||
bootstrapSetupSecureUseSecurityKey.clickableView.debouncedClicks {
|
||||
views.bootstrapSetupSecureUseSecurityKey.clickableView.debouncedClicks {
|
||||
sharedViewModel.handle(BootstrapActions.Start(userWantsToEnterPassphrase = false))
|
||||
}
|
||||
bootstrapSetupSecureUseSecurityPassphrase.clickableView.debouncedClicks {
|
||||
views.bootstrapSetupSecureUseSecurityPassphrase.clickableView.debouncedClicks {
|
||||
sharedViewModel.handle(BootstrapActions.Start(userWantsToEnterPassphrase = true))
|
||||
}
|
||||
}
|
||||
|
@ -53,23 +60,23 @@ class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragme
|
|||
if (state.step is BootstrapStep.FirstForm) {
|
||||
if (state.step.keyBackUpExist) {
|
||||
// Display the set up action
|
||||
bootstrapSetupSecureSubmit.isVisible = true
|
||||
bootstrapSetupSecureUseSecurityKey.isVisible = false
|
||||
bootstrapSetupSecureUseSecurityPassphrase.isVisible = false
|
||||
bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = false
|
||||
views.bootstrapSetupSecureSubmit.isVisible = true
|
||||
views.bootstrapSetupSecureUseSecurityKey.isVisible = false
|
||||
views.bootstrapSetupSecureUseSecurityPassphrase.isVisible = false
|
||||
views.bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = false
|
||||
} else {
|
||||
if (state.step.reset) {
|
||||
bootstrapSetupSecureText.text = getString(R.string.reset_secure_backup_title)
|
||||
bootstrapSetupWarningTextView.isVisible = true
|
||||
views.bootstrapSetupSecureText.text = getString(R.string.reset_secure_backup_title)
|
||||
views.bootstrapSetupWarningTextView.isVisible = true
|
||||
} else {
|
||||
bootstrapSetupSecureText.text = getString(R.string.bottom_sheet_setup_secure_backup_subtitle)
|
||||
bootstrapSetupWarningTextView.isVisible = false
|
||||
views.bootstrapSetupSecureText.text = getString(R.string.bottom_sheet_setup_secure_backup_subtitle)
|
||||
views.bootstrapSetupWarningTextView.isVisible = false
|
||||
}
|
||||
// Choose between create a passphrase or use a recovery key
|
||||
bootstrapSetupSecureSubmit.isVisible = false
|
||||
bootstrapSetupSecureUseSecurityKey.isVisible = true
|
||||
bootstrapSetupSecureUseSecurityPassphrase.isVisible = true
|
||||
bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = true
|
||||
views.bootstrapSetupSecureSubmit.isVisible = false
|
||||
views.bootstrapSetupSecureUseSecurityKey.isVisible = true
|
||||
views.bootstrapSetupSecureUseSecurityPassphrase.isVisible = true
|
||||
views.bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,26 +16,33 @@
|
|||
|
||||
package im.vector.app.features.crypto.recover
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_bootstrap_waiting.*
|
||||
import im.vector.app.databinding.FragmentBootstrapWaitingBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class BootstrapWaitingFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class BootstrapWaitingFragment @Inject constructor()
|
||||
: VectorBaseFragment<FragmentBootstrapWaitingBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_bootstrap_waiting
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapWaitingBinding {
|
||||
return FragmentBootstrapWaitingBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
when (state.step) {
|
||||
is BootstrapStep.Initializing -> {
|
||||
bootstrapLoadingStatusText.isVisible = true
|
||||
bootstrapDescriptionText.isVisible = true
|
||||
bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message
|
||||
views.bootstrapLoadingStatusText.isVisible = true
|
||||
views.bootstrapDescriptionText.isVisible = true
|
||||
views.bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message
|
||||
}
|
||||
// is BootstrapStep.CheckingMigration -> {
|
||||
// bootstrapLoadingStatusText.isVisible = false
|
||||
|
@ -43,8 +50,8 @@ class BootstrapWaitingFragment @Inject constructor() : VectorBaseFragment() {
|
|||
// }
|
||||
else -> {
|
||||
// just show the spinner
|
||||
bootstrapLoadingStatusText.isVisible = false
|
||||
bootstrapDescriptionText.isVisible = false
|
||||
views.bootstrapLoadingStatusText.isVisible = false
|
||||
views.bootstrapDescriptionText.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,10 +16,16 @@
|
|||
|
||||
package im.vector.app.features.crypto.verification
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.databinding.FragmentProgressBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
class QuadSLoadingFragment @Inject constructor() : VectorBaseFragment() {
|
||||
override fun getLayoutResId() = R.layout.fragment_progress
|
||||
class QuadSLoadingFragment @Inject constructor() : VectorBaseFragment<FragmentProgressBinding>() {
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentProgressBinding {
|
||||
return FragmentProgressBinding.inflate(inflater, container, false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,9 @@ import android.app.Dialog
|
|||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -34,6 +36,8 @@ import im.vector.app.core.extensions.exhaustive
|
|||
import im.vector.app.core.extensions.registerStartForActivityResult
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.BottomSheetVerificationBinding
|
||||
import im.vector.app.features.crypto.quads.SharedSecureStorageActivity
|
||||
import im.vector.app.features.crypto.verification.cancel.VerificationCancelFragment
|
||||
import im.vector.app.features.crypto.verification.cancel.VerificationNotMeFragment
|
||||
|
@ -45,8 +49,8 @@ import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrS
|
|||
import im.vector.app.features.crypto.verification.request.VerificationRequestFragment
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.settings.VectorSettingsActivity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME
|
||||
import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
|
||||
|
@ -58,7 +62,7 @@ import timber.log.Timber
|
|||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetVerificationBinding>() {
|
||||
|
||||
@Parcelize
|
||||
data class VerificationArgs(
|
||||
|
@ -84,7 +88,9 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationBinding {
|
||||
return BottomSheetVerificationBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
init {
|
||||
isCancelable = false
|
||||
|
@ -115,7 +121,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
}
|
||||
VerificationBottomSheetViewEvents.GoToSettings -> {
|
||||
dismiss()
|
||||
(activity as? VectorBaseActivity)?.navigator?.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY)
|
||||
(activity as? VectorBaseActivity<*>)?.navigator?.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY)
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
|
@ -152,27 +158,27 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
override fun invalidate() = withState(viewModel) { state ->
|
||||
state.otherUserMxItem?.let { matrixItem ->
|
||||
if (state.isMe) {
|
||||
avatarRenderer.render(matrixItem, otherUserAvatarImageView)
|
||||
avatarRenderer.render(matrixItem, views.otherUserAvatarImageView)
|
||||
if (state.sasTransactionState == VerificationTxState.Verified
|
||||
|| state.qrTransactionState == VerificationTxState.Verified
|
||||
|| state.verifiedFromPrivateKeys) {
|
||||
otherUserShield.setImageResource(R.drawable.ic_shield_trusted)
|
||||
views.otherUserShield.setImageResource(R.drawable.ic_shield_trusted)
|
||||
} else {
|
||||
otherUserShield.setImageResource(R.drawable.ic_shield_warning)
|
||||
views.otherUserShield.setImageResource(R.drawable.ic_shield_warning)
|
||||
}
|
||||
otherUserNameText.text = getString(
|
||||
views.otherUserNameText.text = getString(
|
||||
if (state.selfVerificationMode) R.string.crosssigning_verify_this_session else R.string.crosssigning_verify_session
|
||||
)
|
||||
otherUserShield.isVisible = true
|
||||
views.otherUserShield.isVisible = true
|
||||
} else {
|
||||
avatarRenderer.render(matrixItem, otherUserAvatarImageView)
|
||||
avatarRenderer.render(matrixItem, views.otherUserAvatarImageView)
|
||||
|
||||
if (state.sasTransactionState == VerificationTxState.Verified || state.qrTransactionState == VerificationTxState.Verified) {
|
||||
otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName())
|
||||
otherUserShield.isVisible = true
|
||||
views.otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName())
|
||||
views.otherUserShield.isVisible = true
|
||||
} else {
|
||||
otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName())
|
||||
otherUserShield.isVisible = false
|
||||
views.otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName())
|
||||
views.otherUserShield.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,13 +195,13 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
if (state.userThinkItsNotHim) {
|
||||
otherUserNameText.text = getString(R.string.dialog_title_warning)
|
||||
views.otherUserNameText.text = getString(R.string.dialog_title_warning)
|
||||
showFragment(VerificationNotMeFragment::class, Bundle())
|
||||
return@withState
|
||||
}
|
||||
|
||||
if (state.userWantsToCancel) {
|
||||
otherUserNameText.text = getString(R.string.are_you_sure)
|
||||
views.otherUserNameText.text = getString(R.string.are_you_sure)
|
||||
showFragment(VerificationCancelFragment::class, Bundle())
|
||||
return@withState
|
||||
}
|
||||
|
@ -287,7 +293,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
// Transaction has not yet started
|
||||
if (state.pendingRequest.invoke()?.cancelConclusion != null) {
|
||||
// The request has been declined, we should dismiss
|
||||
otherUserNameText.text = getString(R.string.verification_cancelled)
|
||||
views.otherUserNameText.text = getString(R.string.verification_cancelled)
|
||||
showFragment(VerificationConclusionFragment::class, Bundle().apply {
|
||||
putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args(
|
||||
false,
|
||||
|
|
|
@ -17,24 +17,31 @@
|
|||
package im.vector.app.features.crypto.verification.cancel
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationCancelFragment @Inject constructor(
|
||||
val controller: VerificationCancelController
|
||||
) : VectorBaseFragment(), VerificationCancelController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationCancelController.Listener {
|
||||
|
||||
private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -42,13 +49,13 @@ class VerificationCancelFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -17,24 +17,31 @@
|
|||
package im.vector.app.features.crypto.verification.cancel
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationNotMeFragment @Inject constructor(
|
||||
val controller: VerificationNotMeController
|
||||
) : VectorBaseFragment(), VerificationNotMeController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationNotMeController.Listener {
|
||||
|
||||
private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -42,13 +49,13 @@ class VerificationNotMeFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ package im.vector.app.features.crypto.verification.choose
|
|||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -29,23 +31,27 @@ import im.vector.app.core.platform.VectorBaseFragment
|
|||
import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
|
||||
import im.vector.app.core.utils.checkPermissions
|
||||
import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import im.vector.app.features.qrcode.QrCodeScannerActivity
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationChooseMethodFragment @Inject constructor(
|
||||
val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory,
|
||||
val controller: VerificationChooseMethodController
|
||||
) : VectorBaseFragment(), VerificationChooseMethodController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationChooseMethodController.Listener {
|
||||
|
||||
private val viewModel by fragmentViewModel(VerificationChooseMethodViewModel::class)
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -54,13 +60,13 @@ class VerificationChooseMethodFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ package im.vector.app.features.crypto.verification.conclusion
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -25,15 +27,17 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationConclusionFragment @Inject constructor(
|
||||
val controller: VerificationConclusionController
|
||||
) : VectorBaseFragment(), VerificationConclusionController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationConclusionController.Listener {
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
|
@ -46,7 +50,9 @@ class VerificationConclusionFragment @Inject constructor(
|
|||
|
||||
private val viewModel by fragmentViewModel(VerificationConclusionViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -55,13 +61,13 @@ class VerificationConclusionFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package im.vector.app.features.crypto.verification.emoji
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -24,21 +26,25 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationEmojiCodeFragment @Inject constructor(
|
||||
val viewModelFactory: VerificationEmojiCodeViewModel.Factory,
|
||||
val controller: VerificationEmojiCodeController
|
||||
) : VectorBaseFragment(), VerificationEmojiCodeController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationEmojiCodeController.Listener {
|
||||
|
||||
private val viewModel by fragmentViewModel(VerificationEmojiCodeViewModel::class)
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -47,13 +53,13 @@ class VerificationEmojiCodeFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -18,19 +18,22 @@ package im.vector.app.features.crypto.verification.qrconfirmation
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationQRWaitingFragment @Inject constructor(
|
||||
val controller: VerificationQRWaitingController
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>() {
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
|
@ -38,7 +41,9 @@ class VerificationQRWaitingFragment @Inject constructor(
|
|||
val otherUserName: String
|
||||
) : Parcelable
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -49,11 +54,11 @@ class VerificationQRWaitingFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,25 +16,31 @@
|
|||
package im.vector.app.features.crypto.verification.qrconfirmation
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationQrScannedByOtherFragment @Inject constructor(
|
||||
val controller: VerificationQrScannedByOtherController
|
||||
) : VectorBaseFragment(), VerificationQrScannedByOtherController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationQrScannedByOtherController.Listener {
|
||||
|
||||
private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -46,13 +52,13 @@ class VerificationQrScannedByOtherFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -16,25 +16,31 @@
|
|||
package im.vector.app.features.crypto.verification.request
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.features.crypto.verification.VerificationAction
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class VerificationRequestFragment @Inject constructor(
|
||||
val controller: VerificationRequestController
|
||||
) : VectorBaseFragment(), VerificationRequestController.Listener {
|
||||
) : VectorBaseFragment<BottomSheetVerificationChildFragmentBinding>(),
|
||||
VerificationRequestController.Listener {
|
||||
|
||||
private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class)
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding {
|
||||
return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -42,13 +48,13 @@ class VerificationRequestFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetVerificationRecyclerView.cleanup()
|
||||
views.bottomSheetVerificationRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true)
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
|
|
|
@ -17,8 +17,11 @@ package im.vector.app.features.discovery
|
|||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
|
@ -30,9 +33,11 @@ import im.vector.app.core.extensions.registerStartForActivityResult
|
|||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.ensureProtocol
|
||||
import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.features.discovery.change.SetIdentityServerFragment
|
||||
import im.vector.app.features.settings.VectorSettingsActivity
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||
|
||||
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.terms.TermsService
|
||||
|
@ -41,9 +46,12 @@ import javax.inject.Inject
|
|||
class DiscoverySettingsFragment @Inject constructor(
|
||||
private val controller: DiscoverySettingsController,
|
||||
val viewModelFactory: DiscoverySettingsViewModel.Factory
|
||||
) : VectorBaseFragment(), DiscoverySettingsController.Listener {
|
||||
) : VectorBaseFragment<FragmentGenericRecyclerBinding>(),
|
||||
DiscoverySettingsController.Listener {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_generic_recycler
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding {
|
||||
return FragmentGenericRecyclerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val viewModel by fragmentViewModel(DiscoverySettingsViewModel::class)
|
||||
|
||||
|
@ -55,7 +63,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
|||
sharedViewModel = activityViewModelProvider.get(DiscoverySharedViewModel::class.java)
|
||||
|
||||
controller.listener = this
|
||||
genericRecyclerView.configureWith(controller)
|
||||
views.genericRecyclerView.configureWith(controller)
|
||||
|
||||
sharedViewModel.navigateEvent.observeEvent(this) {
|
||||
when (it) {
|
||||
|
@ -74,7 +82,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
genericRecyclerView.cleanup()
|
||||
views.genericRecyclerView.cleanup()
|
||||
controller.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
@ -85,7 +93,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_discovery_category)
|
||||
(activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_discovery_category)
|
||||
|
||||
// If some 3pids are pending, we can try to check if they have been verified here
|
||||
viewModel.handle(DiscoverySettingsAction.Refresh)
|
||||
|
|
|
@ -17,7 +17,9 @@ package im.vector.app.features.discovery.change
|
|||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.text.toSpannable
|
||||
|
@ -33,17 +35,21 @@ import im.vector.app.core.platform.VectorBaseActivity
|
|||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentSetIdentityServerBinding
|
||||
import im.vector.app.features.discovery.DiscoverySharedViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_set_identity_server.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.terms.TermsService
|
||||
import javax.inject.Inject
|
||||
|
||||
class SetIdentityServerFragment @Inject constructor(
|
||||
val viewModelFactory: SetIdentityServerViewModel.Factory,
|
||||
val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentSetIdentityServerBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_set_identity_server
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSetIdentityServerBinding {
|
||||
return FragmentSetIdentityServerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val viewModel by fragmentViewModel(SetIdentityServerViewModel::class)
|
||||
|
||||
|
@ -147,7 +153,7 @@ class SetIdentityServerFragment @Inject constructor(
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.identity_server)
|
||||
(activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.identity_server)
|
||||
}
|
||||
|
||||
private val termsActivityResultLauncher = registerStartForActivityResult {
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
package im.vector.app.features.grouplist
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
|
@ -29,28 +31,33 @@ import im.vector.app.core.extensions.configureWith
|
|||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.StateView
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentGroupListBinding
|
||||
import im.vector.app.features.home.HomeActivitySharedAction
|
||||
import im.vector.app.features.home.HomeSharedActionViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_group_list.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.group.model.GroupSummary
|
||||
import javax.inject.Inject
|
||||
|
||||
class GroupListFragment @Inject constructor(
|
||||
val groupListViewModelFactory: GroupListViewModel.Factory,
|
||||
private val groupController: GroupSummaryController
|
||||
) : VectorBaseFragment(), GroupSummaryController.Callback {
|
||||
) : VectorBaseFragment<FragmentGroupListBinding>(),
|
||||
GroupSummaryController.Callback {
|
||||
|
||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||
private val viewModel: GroupListViewModel by fragmentViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_group_list
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGroupListBinding {
|
||||
return FragmentGroupListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java)
|
||||
groupController.callback = this
|
||||
stateView.contentView = groupListView
|
||||
groupListView.configureWith(groupController)
|
||||
views.stateView.contentView = views.groupListView
|
||||
views.groupListView.configureWith(groupController)
|
||||
viewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is GroupListViewEvents.OpenGroupSummary -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup)
|
||||
|
@ -60,14 +67,14 @@ class GroupListFragment @Inject constructor(
|
|||
|
||||
override fun onDestroyView() {
|
||||
groupController.callback = null
|
||||
groupListView.cleanup()
|
||||
views.groupListView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
when (state.asyncGroups) {
|
||||
is Incomplete -> stateView.state = StateView.State.Loading
|
||||
is Success -> stateView.state = StateView.State.Content
|
||||
is Incomplete -> views.stateView.state = StateView.State.Loading
|
||||
is Success -> views.stateView.state = StateView.State.Content
|
||||
}
|
||||
groupController.update(state)
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@ import android.content.Intent
|
|||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.GravityCompat
|
||||
|
@ -40,6 +42,7 @@ import im.vector.app.core.platform.ToolbarConfigurable
|
|||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.core.pushers.PushersManager
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.ActivityHomeBinding
|
||||
import im.vector.app.features.disclaimer.showDisclaimerDialog
|
||||
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
|
@ -56,9 +59,9 @@ import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
|||
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
|
||||
import im.vector.app.push.fcm.FcmHelper
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.activity_home.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
|
||||
import org.matrix.android.sdk.api.session.InitialSyncProgressService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
@ -71,7 +74,11 @@ data class HomeActivityArgs(
|
|||
val accountCreation: Boolean
|
||||
) : Parcelable
|
||||
|
||||
class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDetectorSharedViewModel.Factory, ServerBackupStatusViewModel.Factory,
|
||||
class HomeActivity :
|
||||
VectorBaseActivity<ActivityHomeBinding>(),
|
||||
ToolbarConfigurable,
|
||||
UnknownDeviceDetectorSharedViewModel.Factory,
|
||||
ServerBackupStatusViewModel.Factory,
|
||||
NavigationInterceptor {
|
||||
|
||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||
|
@ -98,7 +105,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
}
|
||||
}
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_home
|
||||
override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
|
@ -116,7 +123,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
super.onCreate(savedInstanceState)
|
||||
FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager, vectorPreferences.areNotificationEnabledForDevice())
|
||||
sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java)
|
||||
drawerLayout.addDrawerListener(drawerListener)
|
||||
views.drawerLayout.addDrawerListener(drawerListener)
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java)
|
||||
replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java)
|
||||
|
@ -126,10 +133,10 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
.observe()
|
||||
.subscribe { sharedAction ->
|
||||
when (sharedAction) {
|
||||
is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START)
|
||||
is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START)
|
||||
is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START)
|
||||
is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START)
|
||||
is HomeActivitySharedAction.OpenGroup -> {
|
||||
drawerLayout.closeDrawer(GravityCompat.START)
|
||||
views.drawerLayout.closeDrawer(GravityCompat.START)
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
|
||||
}
|
||||
}.exhaustive
|
||||
|
@ -197,24 +204,24 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
private fun renderState(state: HomeActivityViewState) {
|
||||
when (val status = state.initialSyncProgressServiceStatus) {
|
||||
is InitialSyncProgressService.Status.Idle -> {
|
||||
waiting_view.isVisible = false
|
||||
views.waitingView.root.isVisible = false
|
||||
}
|
||||
is InitialSyncProgressService.Status.Progressing -> {
|
||||
Timber.v("${getString(status.statusText)} ${status.percentProgress}")
|
||||
waiting_view.setOnClickListener {
|
||||
views.waitingView.root.setOnClickListener {
|
||||
// block interactions
|
||||
}
|
||||
waitingHorizontalProgress.apply {
|
||||
views.waitingView.waitingHorizontalProgress.apply {
|
||||
isIndeterminate = false
|
||||
max = 100
|
||||
progress = status.percentProgress
|
||||
isVisible = true
|
||||
}
|
||||
waitingStatusText.apply {
|
||||
views.waitingView.waitingStatusText.apply {
|
||||
text = getString(status.statusText)
|
||||
isVisible = true
|
||||
}
|
||||
waiting_view.isVisible = true
|
||||
views.waitingView.root.isVisible = true
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
|
@ -269,7 +276,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
).apply {
|
||||
colorInt = ThemeUtils.getColor(this@HomeActivity, R.attr.vctr_notice_secondary)
|
||||
contentAction = Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let {
|
||||
// action(it)
|
||||
homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed)
|
||||
it.navigator.openSettings(it, VectorSettingsActivity.EXTRA_DIRECT_ACCESS_NOTIFICATIONS)
|
||||
|
@ -282,7 +289,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed)
|
||||
}, true)
|
||||
addButton(getString(R.string.settings), Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let {
|
||||
// action(it)
|
||||
homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed)
|
||||
it.navigator.openSettings(it, VectorSettingsActivity.EXTRA_DIRECT_ACCESS_NOTIFICATIONS)
|
||||
|
@ -292,7 +299,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
)
|
||||
}
|
||||
|
||||
private fun promptSecurityEvent(userItem: MatrixItem.UserItem?, titleRes: Int, descRes: Int, action: ((VectorBaseActivity) -> Unit)) {
|
||||
private fun promptSecurityEvent(userItem: MatrixItem.UserItem?, titleRes: Int, descRes: Int, action: ((VectorBaseActivity<*>) -> Unit)) {
|
||||
popupAlertManager.postVectorAlert(
|
||||
VerificationVectorAlert(
|
||||
uid = "upgradeSecurity",
|
||||
|
@ -303,7 +310,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
).apply {
|
||||
colorInt = ContextCompat.getColor(this@HomeActivity, R.color.riotx_positive_accent)
|
||||
contentAction = Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let {
|
||||
action(it)
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +328,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
drawerLayout.removeDrawerListener(drawerListener)
|
||||
views.drawerLayout.removeDrawerListener(drawerListener)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
@ -375,8 +382,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet
|
|||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
drawerLayout.closeDrawer(GravityCompat.START)
|
||||
if (views.drawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
views.drawerLayout.closeDrawer(GravityCompat.START)
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import com.airbnb.mvrx.activityViewModel
|
||||
|
@ -33,6 +35,8 @@ import im.vector.app.core.platform.VectorBaseFragment
|
|||
import im.vector.app.core.ui.views.ActiveCallView
|
||||
import im.vector.app.core.ui.views.ActiveCallViewHolder
|
||||
import im.vector.app.core.ui.views.KeysBackupBanner
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentHomeDetailBinding
|
||||
import im.vector.app.features.call.SharedActiveCallViewModel
|
||||
import im.vector.app.features.call.VectorCallActivity
|
||||
import im.vector.app.features.call.WebRtcPeerConnectionManager
|
||||
|
@ -46,7 +50,7 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
import im.vector.app.features.workers.signout.BannerState
|
||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
|
||||
import kotlinx.android.synthetic.main.fragment_home_detail.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.group.model.GroupSummary
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
|
@ -64,7 +68,10 @@ class HomeDetailFragment @Inject constructor(
|
|||
private val alertManager: PopupAlertManager,
|
||||
private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager,
|
||||
private val vectorPreferences: VectorPreferences
|
||||
) : VectorBaseFragment(), KeysBackupBanner.Delegate, ActiveCallView.Callback, ServerBackupStatusViewModel.Factory {
|
||||
) : VectorBaseFragment<FragmentHomeDetailBinding>(),
|
||||
KeysBackupBanner.Delegate,
|
||||
ActiveCallView.Callback,
|
||||
ServerBackupStatusViewModel.Factory {
|
||||
|
||||
private val viewModel: HomeDetailViewModel by fragmentViewModel()
|
||||
private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel()
|
||||
|
@ -73,7 +80,9 @@ class HomeDetailFragment @Inject constructor(
|
|||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||
private lateinit var sharedCallActionViewModel: SharedActiveCallViewModel
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_home_detail
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDetailBinding {
|
||||
return FragmentHomeDetailBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private val activeCallViewHolder = ActiveCallViewHolder()
|
||||
|
||||
|
@ -89,7 +98,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
|
||||
withState(viewModel) {
|
||||
// Update the navigation view if needed (for when we restore the tabs)
|
||||
bottomNavigationView.selectedItemId = it.displayMode.toMenuId()
|
||||
views.bottomNavigationView.selectedItemId = it.displayMode.toMenuId()
|
||||
}
|
||||
|
||||
viewModel.selectSubscribe(this, HomeDetailViewState::groupSummary) { groupSummary ->
|
||||
|
@ -132,8 +141,8 @@ class HomeDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun checkNotificationTabStatus() {
|
||||
val wasVisible = bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible
|
||||
bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab()
|
||||
val wasVisible = views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible
|
||||
views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab()
|
||||
if (wasVisible && !vectorPreferences.labAddNotificationTab()) {
|
||||
// As we hide it check if it's not the current item!
|
||||
withState(viewModel) {
|
||||
|
@ -156,7 +165,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
).apply {
|
||||
colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent)
|
||||
contentAction = Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)
|
||||
?.navigator
|
||||
?.requestSessionVerification(requireContext(), newest.deviceId ?: "")
|
||||
unknownDeviceDetectorSharedViewModel.handle(
|
||||
|
@ -184,7 +193,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
).apply {
|
||||
colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent)
|
||||
contentAction = Runnable {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity)?.let {
|
||||
(weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let {
|
||||
// mark as ignored to avoid showing it again
|
||||
unknownDeviceDetectorSharedViewModel.handle(
|
||||
UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId })
|
||||
|
@ -204,7 +213,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
private fun onGroupChange(groupSummary: GroupSummary?) {
|
||||
groupSummary?.let {
|
||||
// Use GlideApp with activity context to avoid the glideRequests to be paused
|
||||
avatarRenderer.render(it.toMatrixItem(), groupToolbarAvatarImageView, GlideApp.with(requireActivity()))
|
||||
avatarRenderer.render(it.toMatrixItem(), views.groupToolbarAvatarImageView, GlideApp.with(requireActivity()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,20 +221,20 @@ class HomeDetailFragment @Inject constructor(
|
|||
serverBackupStatusViewModel
|
||||
.subscribe(this) {
|
||||
when (val banState = it.bannerState.invoke()) {
|
||||
is BannerState.Setup -> homeKeysBackupBanner.render(KeysBackupBanner.State.Setup(banState.numberOfKeys), false)
|
||||
BannerState.BackingUp -> homeKeysBackupBanner.render(KeysBackupBanner.State.BackingUp, false)
|
||||
is BannerState.Setup -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.Setup(banState.numberOfKeys), false)
|
||||
BannerState.BackingUp -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.BackingUp, false)
|
||||
null,
|
||||
BannerState.Hidden -> homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false)
|
||||
BannerState.Hidden -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false)
|
||||
}
|
||||
}
|
||||
homeKeysBackupBanner.delegate = this
|
||||
views.homeKeysBackupBanner.delegate = this
|
||||
}
|
||||
|
||||
private fun setupActiveCallView() {
|
||||
activeCallViewHolder.bind(
|
||||
activeCallPiP,
|
||||
activeCallView,
|
||||
activeCallPiPWrap,
|
||||
views.activeCallPiP,
|
||||
views.activeCallView,
|
||||
views.activeCallPiPWrap,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
@ -233,17 +242,17 @@ class HomeDetailFragment @Inject constructor(
|
|||
private fun setupToolbar() {
|
||||
val parentActivity = vectorBaseActivity
|
||||
if (parentActivity is ToolbarConfigurable) {
|
||||
parentActivity.configure(groupToolbar)
|
||||
parentActivity.configure(views.groupToolbar)
|
||||
}
|
||||
groupToolbar.title = ""
|
||||
groupToolbarAvatarImageView.debouncedClicks {
|
||||
views.groupToolbar.title = ""
|
||||
views.groupToolbarAvatarImageView.debouncedClicks {
|
||||
sharedActionViewModel.post(HomeActivitySharedAction.OpenDrawer)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupBottomNavigationView() {
|
||||
bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab()
|
||||
bottomNavigationView.setOnNavigationItemSelectedListener {
|
||||
views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab()
|
||||
views.bottomNavigationView.setOnNavigationItemSelectedListener {
|
||||
val displayMode = when (it.itemId) {
|
||||
R.id.bottom_action_people -> RoomListDisplayMode.PEOPLE
|
||||
R.id.bottom_action_rooms -> RoomListDisplayMode.ROOMS
|
||||
|
@ -266,7 +275,7 @@ class HomeDetailFragment @Inject constructor(
|
|||
}
|
||||
|
||||
private fun switchDisplayMode(displayMode: RoomListDisplayMode) {
|
||||
groupToolbarTitleView.setText(displayMode.titleRes)
|
||||
views.groupToolbarTitleView.setText(displayMode.titleRes)
|
||||
updateSelectedFragment(displayMode)
|
||||
}
|
||||
|
||||
|
@ -302,10 +311,10 @@ class HomeDetailFragment @Inject constructor(
|
|||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
Timber.v(it.toString())
|
||||
bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople)
|
||||
bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms)
|
||||
bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
|
||||
syncStateView.render(it.syncState)
|
||||
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople)
|
||||
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms)
|
||||
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
|
||||
views.syncStateView.render(it.syncState)
|
||||
}
|
||||
|
||||
private fun BadgeDrawable.render(count: Int, highlight: Boolean) {
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.app.ActivityOptionsCompat
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -27,12 +29,14 @@ import im.vector.app.core.extensions.observeK
|
|||
import im.vector.app.core.extensions.replaceChildFragment
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.core.utils.startSharePlainTextIntent
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentHomeDrawerBinding
|
||||
import im.vector.app.features.grouplist.GroupListFragment
|
||||
import im.vector.app.features.settings.VectorPreferences
|
||||
import im.vector.app.features.settings.VectorSettingsActivity
|
||||
import im.vector.app.features.usercode.UserCodeActivity
|
||||
import im.vector.app.features.workers.signout.SignOutUiWorker
|
||||
import kotlinx.android.synthetic.main.fragment_home_drawer.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
@ -41,11 +45,13 @@ class HomeDrawerFragment @Inject constructor(
|
|||
private val session: Session,
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment() {
|
||||
) : VectorBaseFragment<FragmentHomeDrawerBinding>() {
|
||||
|
||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_home_drawer
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDrawerBinding {
|
||||
return FragmentHomeDrawerBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -58,40 +64,40 @@ class HomeDrawerFragment @Inject constructor(
|
|||
session.getUserLive(session.myUserId).observeK(viewLifecycleOwner) { optionalUser ->
|
||||
val user = optionalUser?.getOrNull()
|
||||
if (user != null) {
|
||||
avatarRenderer.render(user.toMatrixItem(), homeDrawerHeaderAvatarView)
|
||||
homeDrawerUsernameView.text = user.displayName
|
||||
homeDrawerUserIdView.text = user.userId
|
||||
avatarRenderer.render(user.toMatrixItem(), views.homeDrawerHeaderAvatarView)
|
||||
views.homeDrawerUsernameView.text = user.displayName
|
||||
views.homeDrawerUserIdView.text = user.userId
|
||||
}
|
||||
}
|
||||
// Profile
|
||||
homeDrawerHeader.debouncedClicks {
|
||||
views.homeDrawerHeader.debouncedClicks {
|
||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||
navigator.openSettings(requireActivity(), directAccess = VectorSettingsActivity.EXTRA_DIRECT_ACCESS_GENERAL)
|
||||
}
|
||||
// Settings
|
||||
homeDrawerHeaderSettingsView.debouncedClicks {
|
||||
views.homeDrawerHeaderSettingsView.debouncedClicks {
|
||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||
navigator.openSettings(requireActivity())
|
||||
}
|
||||
// Sign out
|
||||
homeDrawerHeaderSignoutView.debouncedClicks {
|
||||
views.homeDrawerHeaderSignoutView.debouncedClicks {
|
||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||
SignOutUiWorker(requireActivity()).perform()
|
||||
}
|
||||
|
||||
homeDrawerQRCodeButton.debouncedClicks {
|
||||
views.homeDrawerQRCodeButton.debouncedClicks {
|
||||
UserCodeActivity.newIntent(requireContext(), sharedActionViewModel.session.myUserId).let {
|
||||
val options =
|
||||
ActivityOptionsCompat.makeSceneTransitionAnimation(
|
||||
requireActivity(),
|
||||
homeDrawerHeaderAvatarView,
|
||||
ViewCompat.getTransitionName(homeDrawerHeaderAvatarView) ?: ""
|
||||
views.homeDrawerHeaderAvatarView,
|
||||
ViewCompat.getTransitionName(views.homeDrawerHeaderAvatarView) ?: ""
|
||||
)
|
||||
startActivity(it, options.toBundle())
|
||||
}
|
||||
}
|
||||
|
||||
homeDrawerInviteFriendButton.debouncedClicks {
|
||||
views.homeDrawerInviteFriendButton.debouncedClicks {
|
||||
session.permalinkService().createPermalink(sharedActionViewModel.session.myUserId)?.let { permalink ->
|
||||
val text = getString(R.string.invite_friends_text, permalink)
|
||||
|
||||
|
@ -106,8 +112,8 @@ class HomeDrawerFragment @Inject constructor(
|
|||
}
|
||||
|
||||
// Debug menu
|
||||
homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode()
|
||||
homeDrawerHeaderDebugView.debouncedClicks {
|
||||
views.homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode()
|
||||
views.homeDrawerHeaderDebugView.debouncedClicks {
|
||||
sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer)
|
||||
navigator.openDebug(requireActivity())
|
||||
}
|
||||
|
|
|
@ -18,20 +18,26 @@ package im.vector.app.features.home
|
|||
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_loading.*
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentLoadingBinding
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoadingFragment @Inject constructor() : VectorBaseFragment() {
|
||||
class LoadingFragment @Inject constructor() : VectorBaseFragment<FragmentLoadingBinding>() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_loading
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoadingBinding {
|
||||
return FragmentLoadingBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val background = animatedLogoImageView.background
|
||||
val background = views.animatedLogoImageView.background
|
||||
if (background is AnimationDrawable) {
|
||||
background.start()
|
||||
}
|
||||
|
|
|
@ -17,27 +17,34 @@
|
|||
package im.vector.app.features.home.room.breadcrumbs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentBreadcrumbsBinding
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.features.home.room.detail.RoomDetailSharedAction
|
||||
import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel
|
||||
import kotlinx.android.synthetic.main.fragment_breadcrumbs.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class BreadcrumbsFragment @Inject constructor(
|
||||
private val breadcrumbsController: BreadcrumbsController,
|
||||
val breadcrumbsViewModelFactory: BreadcrumbsViewModel.Factory
|
||||
) : VectorBaseFragment(), BreadcrumbsController.Listener {
|
||||
) : VectorBaseFragment<FragmentBreadcrumbsBinding>(),
|
||||
BreadcrumbsController.Listener {
|
||||
|
||||
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
|
||||
private val breadcrumbsViewModel: BreadcrumbsViewModel by fragmentViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_breadcrumbs
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBreadcrumbsBinding {
|
||||
return FragmentBreadcrumbsBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
@ -46,13 +53,13 @@ class BreadcrumbsFragment @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
breadcrumbsRecyclerView.cleanup()
|
||||
views.breadcrumbsRecyclerView.cleanup()
|
||||
breadcrumbsController.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun setupRecyclerView() {
|
||||
breadcrumbsRecyclerView.configureWith(breadcrumbsController, BreadcrumbsAnimator(), hasFixedSize = false)
|
||||
views.breadcrumbsRecyclerView.configureWith(breadcrumbsController, BreadcrumbsAnimator(), hasFixedSize = false)
|
||||
breadcrumbsController.listener = this
|
||||
}
|
||||
|
||||
|
@ -67,6 +74,6 @@ class BreadcrumbsFragment @Inject constructor(
|
|||
}
|
||||
|
||||
fun scrollToTop() {
|
||||
breadcrumbsRecyclerView.scrollToPosition(0)
|
||||
views.breadcrumbsRecyclerView.scrollToPosition(0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ import im.vector.app.features.room.RequireActiveMembershipViewModel
|
|||
import im.vector.app.features.room.RequireActiveMembershipViewState
|
||||
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel
|
||||
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState
|
||||
import kotlinx.android.synthetic.main.activity_room_detail.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDetailActivity :
|
||||
|
|
|
@ -167,10 +167,10 @@ import im.vector.app.features.widgets.WidgetKind
|
|||
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||
import kotlinx.android.synthetic.main.composer_layout.view.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
|
||||
|
||||
import nl.dionsegijn.konfetti.models.Shape
|
||||
import nl.dionsegijn.konfetti.models.Size
|
||||
import org.billcarsonfr.jsonviewer.JSonViewerDialog
|
||||
|
|
|
@ -31,7 +31,7 @@ import androidx.transition.Transition
|
|||
import androidx.transition.TransitionManager
|
||||
import androidx.transition.TransitionSet
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.composer_layout.view.*
|
||||
|
||||
import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.home.room.detail.readreceipts
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.args
|
||||
import im.vector.app.R
|
||||
|
@ -26,11 +28,13 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction
|
||||
import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel
|
||||
import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
@Parcelize
|
||||
|
@ -41,7 +45,9 @@ data class DisplayReadReceiptArgs(
|
|||
/**
|
||||
* Bottom sheet displaying list of read receipts for a given event ordered by descending timestamp
|
||||
*/
|
||||
class DisplayReadReceiptsBottomSheet : VectorBaseBottomSheetDialogFragment(), DisplayReadReceiptsController.Listener {
|
||||
class DisplayReadReceiptsBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListWithTitleBinding>(),
|
||||
DisplayReadReceiptsController.Listener {
|
||||
|
||||
@Inject lateinit var epoxyController: DisplayReadReceiptsController
|
||||
|
||||
|
@ -53,19 +59,21 @@ class DisplayReadReceiptsBottomSheet : VectorBaseBottomSheetDialogFragment(), Di
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
|
||||
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||
bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false)
|
||||
bottomSheetTitle.text = getString(R.string.seen_by)
|
||||
views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false)
|
||||
views.bottomSheetTitle.text = getString(R.string.seen_by)
|
||||
epoxyController.listener = this
|
||||
epoxyController.setData(displayReadReceiptArgs.readReceipts)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.bottomSheetRecyclerView.cleanup()
|
||||
epoxyController.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
|
|
@ -19,22 +19,23 @@ package im.vector.app.features.home.room.detail.search
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import kotlinx.android.synthetic.main.activity_search.*
|
||||
import im.vector.app.databinding.ActivitySearchBinding
|
||||
|
||||
class SearchActivity : VectorBaseActivity() {
|
||||
class SearchActivity : VectorBaseActivity<ActivitySearchBinding>() {
|
||||
|
||||
private val searchFragment: SearchFragment?
|
||||
get() {
|
||||
return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? SearchFragment
|
||||
}
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_search
|
||||
override fun getBinding() = ActivitySearchBinding.inflate(layoutInflater)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
|
@ -43,7 +44,7 @@ class SearchActivity : VectorBaseActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
configureToolbar(searchToolbar)
|
||||
configureToolbar(views.searchToolbar)
|
||||
}
|
||||
|
||||
override fun initUiAndData() {
|
||||
|
@ -51,7 +52,7 @@ class SearchActivity : VectorBaseActivity() {
|
|||
val fragmentArgs: SearchArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG) ?: return
|
||||
addFragment(R.id.searchFragmentContainer, SearchFragment::class.java, fragmentArgs, FRAGMENT_TAG)
|
||||
}
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
views.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
searchFragment?.search(query)
|
||||
return true
|
||||
|
@ -62,7 +63,7 @@ class SearchActivity : VectorBaseActivity() {
|
|||
}
|
||||
})
|
||||
// Open the keyboard immediately
|
||||
searchView.requestFocus()
|
||||
views.searchView.requestFocus()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.home.room.detail.search
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.airbnb.mvrx.Fail
|
||||
|
@ -34,8 +36,10 @@ import im.vector.app.core.extensions.hideKeyboard
|
|||
import im.vector.app.core.extensions.trackItemsVisibilityChange
|
||||
import im.vector.app.core.platform.StateView
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_search.*
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentSearchBinding
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -47,32 +51,36 @@ data class SearchArgs(
|
|||
class SearchFragment @Inject constructor(
|
||||
val viewModelFactory: SearchViewModel.Factory,
|
||||
private val controller: SearchResultController
|
||||
) : VectorBaseFragment(), StateView.EventCallback, SearchResultController.Listener {
|
||||
) : VectorBaseFragment<FragmentSearchBinding>(),
|
||||
StateView.EventCallback,
|
||||
SearchResultController.Listener {
|
||||
|
||||
private val fragmentArgs: SearchArgs by args()
|
||||
private val searchViewModel: SearchViewModel by fragmentViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_search
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSearchBinding {
|
||||
return FragmentSearchBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
stateView.contentView = searchResultRecycler
|
||||
stateView.eventCallback = this
|
||||
views.stateView.contentView = views.searchResultRecycler
|
||||
views.stateView.eventCallback = this
|
||||
|
||||
configureRecyclerView()
|
||||
}
|
||||
|
||||
private fun configureRecyclerView() {
|
||||
searchResultRecycler.trackItemsVisibilityChange()
|
||||
searchResultRecycler.configureWith(controller, showDivider = false)
|
||||
(searchResultRecycler.layoutManager as? LinearLayoutManager)?.stackFromEnd = true
|
||||
views.searchResultRecycler.trackItemsVisibilityChange()
|
||||
views.searchResultRecycler.configureWith(controller, showDivider = false)
|
||||
(views.searchResultRecycler.layoutManager as? LinearLayoutManager)?.stackFromEnd = true
|
||||
controller.listener = this
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
searchResultRecycler?.cleanup()
|
||||
views.searchResultRecycler?.cleanup()
|
||||
controller.listener = null
|
||||
}
|
||||
|
||||
|
@ -80,20 +88,20 @@ class SearchFragment @Inject constructor(
|
|||
if (state.searchResult.isNullOrEmpty()) {
|
||||
when (state.asyncSearchRequest) {
|
||||
is Loading -> {
|
||||
stateView.state = StateView.State.Loading
|
||||
views.stateView.state = StateView.State.Loading
|
||||
}
|
||||
is Fail -> {
|
||||
stateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncSearchRequest.error))
|
||||
views.stateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncSearchRequest.error))
|
||||
}
|
||||
is Success -> {
|
||||
stateView.state = StateView.State.Empty(
|
||||
views.stateView.state = StateView.State.Empty(
|
||||
title = getString(R.string.search_no_results),
|
||||
image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_search_no_results))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
controller.setData(state)
|
||||
stateView.state = StateView.State.Content
|
||||
views.stateView.state = StateView.State.Content
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package im.vector.app.features.home.room.detail.timeline.action
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
|
@ -24,14 +26,17 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Bottom sheet fragment that shows a message preview with list of contextual actions
|
||||
*/
|
||||
class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), MessageActionsEpoxyController.MessageActionsEpoxyControllerListener {
|
||||
class MessageActionsBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListBinding>(),
|
||||
MessageActionsEpoxyController.MessageActionsEpoxyControllerListener {
|
||||
|
||||
@Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory
|
||||
@Inject lateinit var messageActionsEpoxyController: MessageActionsEpoxyController
|
||||
|
@ -46,17 +51,19 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding {
|
||||
return BottomSheetGenericListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||
bottomSheetRecyclerView.configureWith(messageActionsEpoxyController, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.bottomSheetRecyclerView.configureWith(messageActionsEpoxyController, hasFixedSize = false, disableItemAnimation = true)
|
||||
messageActionsEpoxyController.listener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.bottomSheetRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
|
@ -76,8 +83,8 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message
|
|||
if (eventAction is EventSharedAction.ReportContent) {
|
||||
// Toggle report menu
|
||||
// Enable item animation
|
||||
if (bottomSheetRecyclerView.itemAnimator == null) {
|
||||
bottomSheetRecyclerView.itemAnimator = MessageActionsAnimator()
|
||||
if (views.bottomSheetRecyclerView.itemAnimator == null) {
|
||||
views.bottomSheetRecyclerView.itemAnimator = MessageActionsAnimator()
|
||||
}
|
||||
viewModel.handle(MessageActionsAction.ToggleReportMenu)
|
||||
} else {
|
||||
|
|
|
@ -18,7 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.action
|
|||
|
||||
import android.os.Parcelable
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class TimelineEventFragmentArgs(
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
package im.vector.app.features.home.room.detail.timeline.edithistory
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -25,16 +27,19 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.app.features.html.EventHtmlRenderer
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying list of edits for a given event ordered by timestamp
|
||||
*/
|
||||
class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
||||
class ViewEditHistoryBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListWithTitleBinding>() {
|
||||
|
||||
private val viewModel: ViewEditHistoryViewModel by fragmentViewModel(ViewEditHistoryViewModel::class)
|
||||
|
||||
|
@ -49,19 +54,21 @@ class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() {
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
|
||||
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
bottomSheetRecyclerView.configureWith(
|
||||
views.bottomSheetRecyclerView.configureWith(
|
||||
epoxyController,
|
||||
showDivider = true,
|
||||
hasFixedSize = false)
|
||||
bottomSheetTitle.text = context?.getString(R.string.message_edits)
|
||||
views.bottomSheetTitle.text = context?.getString(R.string.message_edits)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.bottomSheetRecyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package im.vector.app.features.home.room.detail.timeline.item
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import org.matrix.android.sdk.internal.session.room.VerificationState
|
||||
|
|
|
@ -23,7 +23,7 @@ import android.widget.LinearLayout
|
|||
import androidx.core.content.withStyledAttributes
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import kotlinx.android.synthetic.main.item_timeline_event_poll_result_item.view.*
|
||||
|
||||
|
||||
class PollResultLineView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.home.room.detail.timeline.reactions
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -26,17 +28,21 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding
|
||||
import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction
|
||||
import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel
|
||||
import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs
|
||||
import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.*
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying list of reactions for a given event ordered by timestamp
|
||||
*/
|
||||
class ViewReactionsBottomSheet : VectorBaseBottomSheetDialogFragment(), ViewReactionsEpoxyController.Listener {
|
||||
class ViewReactionsBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListWithTitleBinding>(),
|
||||
ViewReactionsEpoxyController.Listener {
|
||||
|
||||
private val viewModel: ViewReactionsViewModel by fragmentViewModel(ViewReactionsViewModel::class)
|
||||
|
||||
|
@ -49,18 +55,20 @@ class ViewReactionsBottomSheet : VectorBaseBottomSheetDialogFragment(), ViewReac
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
|
||||
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java)
|
||||
bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false, showDivider = true)
|
||||
bottomSheetTitle.text = context?.getString(R.string.reactions)
|
||||
views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false, showDivider = true)
|
||||
views.bottomSheetTitle.text = context?.getString(R.string.reactions)
|
||||
epoxyController.listener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.bottomSheetRecyclerView.cleanup()
|
||||
epoxyController.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import kotlinx.android.synthetic.main.url_preview.view.*
|
||||
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.session.media.PreviewUrlData
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import android.util.AttributeSet
|
|||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.view_room_widgets_banner.view.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||
|
||||
class RoomWidgetsBannerView @JvmOverloads constructor(
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
package im.vector.app.features.home.room.detail.widget
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.airbnb.mvrx.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
|
@ -26,18 +28,22 @@ import im.vector.app.core.extensions.cleanup
|
|||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding
|
||||
import im.vector.app.features.home.room.detail.RoomDetailAction
|
||||
import im.vector.app.features.home.room.detail.RoomDetailViewModel
|
||||
import im.vector.app.features.home.room.detail.RoomDetailViewState
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Bottom sheet displaying active widgets in a room
|
||||
*/
|
||||
class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidgetsController.Listener {
|
||||
class RoomWidgetsBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListWithTitleBinding>(),
|
||||
RoomWidgetsController.Listener {
|
||||
|
||||
@Inject lateinit var epoxyController: RoomWidgetsController
|
||||
@Inject lateinit var colorProvider: ColorProvider
|
||||
|
@ -49,14 +55,16 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding {
|
||||
return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false)
|
||||
bottomSheetTitle.text = getString(R.string.active_widgets_title)
|
||||
bottomSheetTitle.textSize = 20f
|
||||
bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false)
|
||||
views.bottomSheetTitle.text = getString(R.string.active_widgets_title)
|
||||
views.bottomSheetTitle.textSize = 20f
|
||||
views.bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary))
|
||||
epoxyController.listener = this
|
||||
roomDetailViewModel.asyncSubscribe(this, RoomDetailViewState::activeRoomWidgets) {
|
||||
epoxyController.setData(it)
|
||||
|
@ -64,7 +72,7 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.bottomSheetRecyclerView.cleanup()
|
||||
epoxyController.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
|
|
@ -19,24 +19,26 @@ package im.vector.app.features.home.room.filtered
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivityFilteredRoomsBinding
|
||||
import im.vector.app.features.home.RoomListDisplayMode
|
||||
import im.vector.app.features.home.room.list.RoomListFragment
|
||||
import im.vector.app.features.home.room.list.RoomListParams
|
||||
import kotlinx.android.synthetic.main.activity_filtered_rooms.*
|
||||
|
||||
class FilteredRoomsActivity : VectorBaseActivity() {
|
||||
|
||||
class FilteredRoomsActivity : VectorBaseActivity<ActivityFilteredRoomsBinding>() {
|
||||
|
||||
private val roomListFragment: RoomListFragment?
|
||||
get() {
|
||||
return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomListFragment
|
||||
}
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_filtered_rooms
|
||||
override fun getBinding() = ActivityFilteredRoomsBinding.inflate(layoutInflater)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
|
@ -44,12 +46,12 @@ class FilteredRoomsActivity : VectorBaseActivity() {
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
configureToolbar(filteredRoomsToolbar)
|
||||
configureToolbar(views.filteredRoomsToolbar)
|
||||
if (isFirstCreation()) {
|
||||
val params = RoomListParams(RoomListDisplayMode.FILTERED)
|
||||
replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG)
|
||||
}
|
||||
filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
views.filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
return true
|
||||
}
|
||||
|
@ -60,7 +62,7 @@ class FilteredRoomsActivity : VectorBaseActivity() {
|
|||
}
|
||||
})
|
||||
// Open the keyboard immediately
|
||||
filteredRoomsSearchView.requestFocus()
|
||||
views.filteredRoomsSearchView.requestFocus()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -18,9 +18,11 @@ package im.vector.app.features.home.room.list
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -40,6 +42,8 @@ import im.vector.app.core.extensions.exhaustive
|
|||
import im.vector.app.core.platform.OnBackPressed
|
||||
import im.vector.app.core.platform.StateView
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import im.vector.app.databinding.FragmentRoomListBinding
|
||||
import im.vector.app.features.home.RoomListDisplayMode
|
||||
import im.vector.app.features.home.room.list.actions.RoomListActionsArgs
|
||||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
|
||||
|
@ -47,8 +51,8 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
|
|||
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
|
||||
import im.vector.app.features.home.room.list.widget.NotifsFabMenuView
|
||||
import im.vector.app.features.notifications.NotificationDrawerManager
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_room_list.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||
|
@ -66,7 +70,10 @@ class RoomListFragment @Inject constructor(
|
|||
val roomListViewModelFactory: RoomListViewModel.Factory,
|
||||
private val notificationDrawerManager: NotificationDrawerManager,
|
||||
private val sharedViewPool: RecyclerView.RecycledViewPool
|
||||
) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, NotifsFabMenuView.Listener {
|
||||
) : VectorBaseFragment<FragmentRoomListBinding>(),
|
||||
RoomSummaryController.Listener,
|
||||
OnBackPressed,
|
||||
NotifsFabMenuView.Listener {
|
||||
|
||||
private var modelBuildListener: OnModelBuildFinishedListener? = null
|
||||
private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel
|
||||
|
@ -74,7 +81,9 @@ class RoomListFragment @Inject constructor(
|
|||
private val roomListViewModel: RoomListViewModel by fragmentViewModel()
|
||||
private lateinit var stateRestorer: LayoutManagerStateRestorer
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_room_list
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomListBinding {
|
||||
return FragmentRoomListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
private var hasUnreadRooms = false
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ package im.vector.app.features.home.room.list.actions
|
|||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
|
@ -27,9 +29,10 @@ import im.vector.app.core.di.ScreenComponent
|
|||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetGenericListBinding
|
||||
import im.vector.app.features.navigation.Navigator
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.bottom_sheet_generic_list.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
@Parcelize
|
||||
|
@ -47,7 +50,9 @@ data class RoomListActionsArgs(
|
|||
/**
|
||||
* Bottom sheet fragment that shows room information with list of contextual actions
|
||||
*/
|
||||
class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener {
|
||||
class RoomListQuickActionsBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetGenericListBinding>(),
|
||||
RoomListQuickActionsEpoxyController.Listener {
|
||||
|
||||
private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel
|
||||
@Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool
|
||||
|
@ -63,17 +68,19 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R
|
|||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutResId() = R.layout.bottom_sheet_generic_list
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding {
|
||||
return BottomSheetGenericListBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java)
|
||||
bottomSheetRecyclerView.configureWith(roomListActionsEpoxyController, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
|
||||
views.views.bottomSheetRecyclerView.configureWith(roomListActionsEpoxyController, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true)
|
||||
roomListActionsEpoxyController.listener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
bottomSheetRecyclerView.cleanup()
|
||||
views.views.bottomSheetRecyclerView.cleanup()
|
||||
roomListActionsEpoxyController.listener = null
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout
|
|||
import androidx.core.view.isVisible
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import im.vector.app.R
|
||||
import kotlinx.android.synthetic.main.motion_notifs_fab_menu_merge.view.*
|
||||
|
||||
|
||||
class NotifsFabMenuView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0) : MotionLayout(context, attrs, defStyleAttr) {
|
||||
|
|
|
@ -45,8 +45,8 @@ import im.vector.app.features.userdirectory.UserListSharedAction
|
|||
import im.vector.app.features.userdirectory.UserListSharedActionViewModel
|
||||
import im.vector.app.features.userdirectory.UserListViewModel
|
||||
import im.vector.app.features.userdirectory.UserListViewState
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.activity.*
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
import org.matrix.android.sdk.api.failure.Failure
|
||||
import java.net.HttpURLConnection
|
||||
import javax.inject.Inject
|
||||
|
|
|
@ -19,13 +19,15 @@ package im.vector.app.features.invite
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.HasScreenInjector
|
||||
import im.vector.app.core.platform.ButtonStateView
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import kotlinx.android.synthetic.main.vector_invite_view.view.*
|
||||
|
||||
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
|
@ -44,6 +46,13 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||
SMALL
|
||||
}
|
||||
|
||||
private val inviteAvatarView: ImageView
|
||||
private val inviteLabelView: TextView
|
||||
private val inviteNameView: TextView
|
||||
private val inviteIdentifierView: TextView
|
||||
private val inviteAcceptView: ButtonStateView
|
||||
private val inviteRejectView: ButtonStateView
|
||||
|
||||
@Inject lateinit var avatarRenderer: AvatarRenderer
|
||||
var callback: Callback? = null
|
||||
|
||||
|
@ -52,6 +61,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||
context.injector().inject(this)
|
||||
}
|
||||
View.inflate(context, R.layout.vector_invite_view, this)
|
||||
inviteAcceptView = findViewById(R.id.inviteAcceptView)
|
||||
inviteAcceptView.callback = object : ButtonStateView.Callback {
|
||||
override fun onButtonClicked() {
|
||||
callback?.onAcceptInvite()
|
||||
|
@ -62,6 +72,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||
}
|
||||
}
|
||||
|
||||
inviteRejectView = findViewById(R.id.inviteRejectView)
|
||||
inviteRejectView.callback = object : ButtonStateView.Callback {
|
||||
override fun onButtonClicked() {
|
||||
callback?.onRejectInvite()
|
||||
|
@ -71,6 +82,11 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib
|
|||
callback?.onRejectInvite()
|
||||
}
|
||||
}
|
||||
|
||||
inviteAvatarView = findViewById(R.id.inviteAvatarView)
|
||||
inviteLabelView = findViewById(R.id.inviteLabelView)
|
||||
inviteNameView = findViewById(R.id.inviteNameView)
|
||||
inviteIdentifierView = findViewById(R.id.inviteIdentifierView)
|
||||
}
|
||||
|
||||
fun render(sender: RoomMemberSummary, mode: Mode = Mode.LARGE, changeMembershipState: ChangeMembershipState) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue