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