From 706736273c6b80ecf5f32b8ed5d8295bbaede2a2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 16 Dec 2020 00:46:52 +0100 Subject: [PATCH] Migrate to ViewBindings (#1072) - WIP --- CHANGES.md | 2 +- attachment-viewer/build.gradle | 5 +- .../AttachmentViewerActivity.kt | 52 +++---- matrix-sdk-android/build.gradle | 6 +- .../sdk/api/auth/data/SsoIdentityProvider.kt | 2 +- .../session/content/ContentAttachmentData.kt | 2 +- .../LocalizedFlowDataLoginTerms.kt | 2 +- .../crypto/attachments/ElementToDecrypt.kt | 2 +- multipicker/build.gradle | 2 +- .../root/src/app_package/Fragment.kt.ftl | 2 +- vector/build.gradle | 10 +- .../debug/DebugMaterialThemeActivity.kt | 2 +- .../app/features/debug/DebugMenuActivity.kt | 24 ++-- .../app/features/debug/TestLinkifyActivity.kt | 2 +- .../debug/sas/DebugSasEmojiActivity.kt | 6 +- .../core/dialogs/ConfirmationDialogBuilder.kt | 2 +- .../im/vector/app/core/extensions/Activity.kt | 24 ++-- .../im/vector/app/core/extensions/Fragment.kt | 25 ++-- .../app/core/platform/ButtonStateView.kt | 2 +- .../core/platform/SimpleFragmentActivity.kt | 45 +++--- .../im/vector/app/core/platform/StateView.kt | 2 +- .../app/core/platform/VectorBaseActivity.kt | 31 ++-- .../VectorBaseBottomSheetDialogFragment.kt | 19 ++- .../app/core/platform/VectorBaseFragment.kt | 29 ++-- .../core/ui/bottomsheet/BottomSheetGeneric.kt | 16 ++- .../core/ui/views/BottomSheetActionButton.kt | 28 ++-- .../app/core/ui/views/JumpToReadMarkerView.kt | 2 +- .../app/core/ui/views/KeysBackupBanner.kt | 2 +- .../app/core/ui/views/NotificationAreaView.kt | 2 +- .../app/core/ui/views/PasswordStrengthBar.kt | 2 +- .../app/core/ui/views/ReadReceiptsView.kt | 2 +- .../im/vector/app/features/MainActivity.kt | 8 +- .../preview/AttachmentsPreviewActivity.kt | 6 +- .../preview/AttachmentsPreviewFragment.kt | 36 ++--- .../features/call/CallControlsBottomSheet.kt | 42 +++--- .../app/features/call/CallControlsView.kt | 41 ++++-- .../app/features/call/VectorCallActivity.kt | 97 +++++++------ .../call/conference/VectorJitsiActivity.kt | 12 +- .../contactsbook/ContactsBookFragment.kt | 29 ++-- .../createdirect/CreateDirectRoomActivity.kt | 2 +- .../CreateDirectRoomByQrCodeFragment.kt | 20 ++- .../KeysBackupRestoreFromKeyFragment.kt | 30 ++-- ...KeysBackupRestoreFromPassphraseFragment.kt | 30 ++-- .../KeysBackupRestoreSuccessFragment.kt | 22 +-- .../settings/KeysBackupSettingsFragment.kt | 16 ++- .../setup/KeysBackupSetupStep1Fragment.kt | 20 ++- .../setup/KeysBackupSetupStep2Fragment.kt | 12 +- .../setup/KeysBackupSetupStep3Fragment.kt | 12 +- .../quads/SharedSecureStorageActivity.kt | 4 +- .../quads/SharedSecuredStorageKeyFragment.kt | 12 +- .../SharedSecuredStoragePassphraseFragment.kt | 40 +++--- .../SharedSecuredStorageResetAllFragment.kt | 21 ++- .../BootstrapAccountPasswordFragment.kt | 16 ++- .../crypto/recover/BootstrapBottomSheet.kt | 62 ++++---- .../recover/BootstrapConclusionFragment.kt | 16 ++- .../BootstrapConfirmPassphraseFragment.kt | 13 +- .../BootstrapEnterPassphraseFragment.kt | 45 +++--- .../recover/BootstrapMigrateBackupFragment.kt | 14 +- .../BootstrapSaveRecoveryKeyFragment.kt | 22 +-- .../BootstrapSetupRecoveryKeyFragment.kt | 43 +++--- .../recover/BootstrapWaitingFragment.kt | 23 +-- .../verification/QuadSLoadingFragment.kt | 10 +- .../verification/VerificationBottomSheet.kt | 42 +++--- .../cancel/VerificationCancelFragment.kt | 17 ++- .../cancel/VerificationNotMeFragment.kt | 17 ++- .../VerificationChooseMethodFragment.kt | 16 ++- .../VerificationConclusionFragment.kt | 18 ++- .../emoji/VerificationEmojiCodeFragment.kt | 16 ++- .../VerificationQRWaitingFragment.kt | 17 ++- .../VerificationQrScannedByOtherFragment.kt | 16 ++- .../request/VerificationRequestFragment.kt | 16 ++- .../discovery/DiscoverySettingsFragment.kt | 20 ++- .../change/SetIdentityServerFragment.kt | 14 +- .../features/grouplist/GroupListFragment.kt | 23 +-- .../vector/app/features/home/HomeActivity.kt | 49 ++++--- .../app/features/home/HomeDetailFragment.kt | 61 ++++---- .../app/features/home/HomeDrawerFragment.kt | 36 +++-- .../app/features/home/LoadingFragment.kt | 14 +- .../room/breadcrumbs/BreadcrumbsFragment.kt | 19 ++- .../home/room/detail/RoomDetailActivity.kt | 4 +- .../home/room/detail/RoomDetailFragment.kt | 8 +- .../room/detail/composer/TextComposerView.kt | 2 +- .../DisplayReadReceiptsBottomSheet.kt | 22 ++- .../home/room/detail/search/SearchActivity.kt | 13 +- .../home/room/detail/search/SearchFragment.kt | 36 +++-- .../action/MessageActionsBottomSheet.kt | 21 ++- .../action/TimelineEventFragmentArgs.kt | 2 +- .../edithistory/ViewEditHistoryBottomSheet.kt | 19 ++- .../timeline/item/MessageInformationData.kt | 2 +- .../timeline/item/PollResultLineView.kt | 2 +- .../reactions/ViewReactionsBottomSheet.kt | 20 ++- .../detail/timeline/url/PreviewUrlView.kt | 2 +- .../detail/widget/RoomWidgetsBannerView.kt | 2 +- .../detail/widget/RoomWidgetsBottomSheet.kt | 24 ++-- .../room/filtered/FilteredRoomsActivity.kt | 14 +- .../home/room/list/RoomListFragment.kt | 17 ++- .../RoomListQuickActionsBottomSheet.kt | 19 ++- .../room/list/widget/NotifsFabMenuView.kt | 2 +- .../invite/InviteUsersToRoomActivity.kt | 4 +- .../app/features/invite/VectorInviteView.kt | 18 ++- .../app/features/link/LinkHandlerActivity.kt | 6 +- .../features/login/AbstractLoginFragment.kt | 3 +- .../login/AbstractSSOLoginFragment.kt | 3 +- .../app/features/login/LoginActivity.kt | 10 +- .../features/login/LoginCaptchaFragment.kt | 26 ++-- .../vector/app/features/login/LoginConfig.kt | 2 +- .../app/features/login/LoginFragment.kt | 132 +++++++++-------- .../LoginGenericTextInputFormFragment.kt | 14 +- .../im/vector/app/features/login/LoginMode.kt | 2 +- .../login/LoginResetPasswordFragment.kt | 12 +- ...inResetPasswordMailConfirmationFragment.kt | 16 ++- .../LoginResetPasswordSuccessFragment.kt | 15 +- .../login/LoginServerSelectionFragment.kt | 26 ++-- .../login/LoginServerUrlFormFragment.kt | 12 +- .../LoginSignUpSignInSelectionFragment.kt | 12 +- .../app/features/login/LoginSplashFragment.kt | 14 +- .../login/LoginWaitForEmailFragment.kt | 16 ++- .../app/features/login/LoginWebFragment.kt | 36 +++-- .../login/terms/LoginTermsFragment.kt | 22 +-- .../features/matrixto/MatrixToBottomSheet.kt | 51 ++++--- .../features/media/BigImageViewerActivity.kt | 13 +- .../features/media/ImageContentRenderer.kt | 2 +- .../media/VectorAttachmentViewerActivity.kt | 2 +- .../features/media/VideoContentRenderer.kt | 2 +- .../permalink/PermalinkHandlerActivity.kt | 5 +- .../im/vector/app/features/pin/PinActivity.kt | 5 +- .../im/vector/app/features/pin/PinFragment.kt | 12 +- .../features/qrcode/QrCodeScannerActivity.kt | 5 +- .../features/qrcode/QrCodeScannerFragment.kt | 18 ++- .../features/rageshake/BugReportActivity.kt | 86 +++++------ .../reactions/EmojiChooserFragment.kt | 16 ++- .../reactions/EmojiReactionPickerActivity.kt | 21 +-- .../reactions/EmojiSearchResultFragment.kt | 15 +- .../roomdirectory/PublicRoomsFragment.kt | 31 ++-- .../roomdirectory/RoomDirectoryActivity.kt | 5 +- .../createroom/CreateRoomActivity.kt | 5 +- .../createroom/CreateRoomFragment.kt | 30 ++-- .../picker/RoomDirectoryPickerFragment.kt | 22 ++- .../roompreview/RoomPreviewActivity.kt | 7 +- .../RoomPreviewNoPreviewFragment.kt | 12 +- .../RoomMemberProfileFragment.kt | 17 ++- .../devices/DeviceListBottomSheet.kt | 13 +- .../devices/DeviceListFragment.kt | 19 ++- .../devices/DeviceTrustInfoActionFragment.kt | 19 ++- .../powerlevel/EditPowerLevelDialogs.kt | 2 +- .../roomprofile/RoomProfileFragment.kt | 18 ++- .../roomprofile/alias/RoomAliasFragment.kt | 30 ++-- .../alias/detail/RoomAliasBottomSheet.kt | 19 ++- .../banned/RoomBannedMemberListFragment.kt | 28 ++-- .../members/RoomMemberListFragment.kt | 21 ++- .../settings/RoomSettingsFragment.kt | 29 ++-- .../RoomHistoryVisibilityBottomSheet.kt | 2 +- .../joinrule/RoomJoinRuleBottomSheet.kt | 2 +- .../uploads/RoomUploadsFragment.kt | 27 ++-- .../uploads/files/RoomUploadsFilesFragment.kt | 30 ++-- .../uploads/media/RoomUploadsMediaFragment.kt | 37 ++--- .../settings/VectorSettingsActivity.kt | 9 +- .../settings/VectorSettingsBaseFragment.kt | 4 +- ...ttingsNotificationsTroubleshootFragment.kt | 14 +- .../deactivation/DeactivateAccountFragment.kt | 14 +- .../CrossSigningSettingsFragment.kt | 20 ++- .../DeviceVerificationInfoBottomSheet.kt | 22 ++- .../devices/VectorSettingsDevicesFragment.kt | 32 +++-- .../settings/devtools/AccountDataFragment.kt | 19 ++- .../GossipingEventsPaperTrailFragment.kt | 16 ++- .../IncomingKeyRequestListFragment.kt | 15 +- .../settings/devtools/KeyRequestsFragment.kt | 27 ++-- .../OutgoingKeyRequestListFragment.kt | 16 ++- .../VectorSettingsIgnoredUsersFragment.kt | 30 ++-- .../settings/locale/LocalePickerFragment.kt | 21 ++- .../settings/push/PushGatewaysFragment.kt | 18 ++- .../settings/push/PushRulesFragment.kt | 18 ++- .../threepids/ThreePidsSettingsFragment.kt | 18 ++- ...ficationTroubleshootRecyclerViewAdapter.kt | 2 +- .../features/share/IncomingShareActivity.kt | 5 +- .../features/share/IncomingShareFragment.kt | 27 ++-- .../vector/app/features/share/SharedData.kt | 2 +- .../signout/hard/SignedOutActivity.kt | 10 +- .../signout/soft/SoftLogoutActivity.kt | 2 +- .../signout/soft/SoftLogoutFragment.kt | 18 ++- .../app/features/sync/widget/SyncStateView.kt | 2 +- .../app/features/terms/ReviewTermsFragment.kt | 15 +- .../app/features/terms/ServiceTermsArgs.kt | 2 +- .../features/usercode/ScanUserCodeFragment.kt | 12 +- .../features/usercode/ShowUserCodeFragment.kt | 26 ++-- .../app/features/usercode/UserCodeActivity.kt | 16 ++- .../userdirectory/UserListFragment.kt | 45 +++--- .../userdirectory/UserListFragmentArgs.kt | 2 +- .../webview/ConsentWebViewEventListener.kt | 4 +- .../features/webview/VectorWebViewActivity.kt | 24 ++-- .../webview/WebViewEventListenerFactory.kt | 2 +- .../app/features/webview/WebViewMode.kt | 4 +- .../app/features/widgets/WidgetActivity.kt | 15 +- .../app/features/widgets/WidgetFragment.kt | 17 ++- .../RoomWidgetPermissionBottomSheet.kt | 25 ++-- .../signout/SignOutBottomSheetActionButton.kt | 2 +- .../SignOutBottomSheetDialogFragment.kt | 134 ++++++++++-------- vector/src/main/res/layout/activity.xml | 4 +- vector/src/main/res/layout/activity_home.xml | 4 +- .../main/res/layout/activity_room_detail.xml | 4 +- .../main/res/layout/fragment_create_room.xml | 4 +- .../res/layout/fragment_generic_recycler.xml | 4 +- .../res/layout/fragment_matrix_profile.xml | 4 +- .../layout/fragment_room_setting_generic.xml | 4 +- 204 files changed, 2225 insertions(+), 1380 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index a2029b9901..e629dd35f2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -23,7 +23,7 @@ Test: - Other changes: - - + - Migrate to ViewBindings (#1072) Changes in Element 1.0.12 (2020-12-15) =================================================== diff --git a/attachment-viewer/build.gradle b/attachment-viewer/build.gradle index 59ba6c4500..d8cd7d0c98 100644 --- a/attachment-viewer/build.gradle +++ b/attachment-viewer/build.gradle @@ -16,7 +16,6 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' buildscript { repositories { @@ -55,6 +54,10 @@ android { kotlinOptions { jvmTarget = '1.8' } + + buildFeatures { + viewBinding true + } } dependencies { diff --git a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt index 71ce436cf2..ea325a2674 100644 --- a/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt +++ b/attachment-viewer/src/main/java/im/vector/lib/attachmentviewer/AttachmentViewerActivity.kt @@ -33,7 +33,8 @@ import androidx.core.view.isVisible import androidx.core.view.updatePadding import androidx.transition.TransitionManager import androidx.viewpager2.widget.ViewPager2 -import kotlinx.android.synthetic.main.activity_attachment_viewer.* +import im.vector.lib.attachmentviewer.databinding.ActivityAttachmentViewerBinding + import java.lang.ref.WeakReference import kotlin.math.abs @@ -50,12 +51,14 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private var overlayView: View? = null set(value) { if (value == overlayView) return - overlayView?.let { rootContainer.removeView(it) } - rootContainer.addView(value) + overlayView?.let { views.rootContainer.removeView(it) } + views.rootContainer.addView(value) value?.updatePadding(top = topInset, bottom = bottomInset) field = value } + private lateinit var views: ActivityAttachmentViewerBinding + private lateinit var swipeDismissHandler: SwipeToDismissHandler private lateinit var directionDetector: SwipeDirectionDetector private lateinit var scaleDetector: ScaleGestureDetector @@ -95,17 +98,18 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION) - setContentView(R.layout.activity_attachment_viewer) - attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL + views = ActivityAttachmentViewerBinding.inflate(layoutInflater) + setContentView(views.root) + views.attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL attachmentsAdapter = AttachmentsAdapter() - attachmentPager.adapter = attachmentsAdapter - imageTransitionView = transitionImageView + views.attachmentPager.adapter = attachmentsAdapter + imageTransitionView = views.transitionImageView transitionImageContainer = findViewById(R.id.transitionImageContainer) - pager2 = attachmentPager + pager2 = views.attachmentPager directionDetector = createSwipeDirectionDetector() gestureDetector = createGestureDetector() - attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + views.attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageScrollStateChanged(state: Int) { isImagePagerIdle = state == ViewPager2.SCROLL_STATE_IDLE } @@ -116,12 +120,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi }) swipeDismissHandler = createSwipeToDismissHandler() - rootContainer.setOnTouchListener(swipeDismissHandler) - rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = dismissContainer.height / 4 } + views.rootContainer.setOnTouchListener(swipeDismissHandler) + views.rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = views.dismissContainer.height / 4 } scaleDetector = createScaleGestureDetector() - ViewCompat.setOnApplyWindowInsetsListener(rootContainer) { _, insets -> + ViewCompat.setOnApplyWindowInsetsListener(views.rootContainer) { _, insets -> overlayView?.updatePadding(top = insets.systemWindowInsetTop, bottom = insets.systemWindowInsetBottom) topInset = insets.systemWindowInsetTop bottomInset = insets.systemWindowInsetBottom @@ -170,7 +174,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi if (swipeDirection == null && (scaleDetector.isInProgress || ev.pointerCount > 1 || wasScaled)) { wasScaled = true // Log.v("ATTACHEMENTS", "dispatch to pager") - return attachmentPager.dispatchTouchEvent(ev) + return views.attachmentPager.dispatchTouchEvent(ev) } // Log.v("ATTACHEMENTS", "is current item scaled ${isScaled()}") @@ -196,16 +200,16 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private fun handleEventActionDown(event: MotionEvent) { swipeDirection = null wasScaled = false - attachmentPager.dispatchTouchEvent(event) + views.attachmentPager.dispatchTouchEvent(event) - swipeDismissHandler.onTouch(rootContainer, event) + swipeDismissHandler.onTouch(views.rootContainer, event) isOverlayWasClicked = dispatchOverlayTouch(event) } private fun handleEventActionUp(event: MotionEvent) { // wasDoubleTapped = false - swipeDismissHandler.onTouch(rootContainer, event) - attachmentPager.dispatchTouchEvent(event) + swipeDismissHandler.onTouch(views.rootContainer, event) + views.attachmentPager.dispatchTouchEvent(event) isOverlayWasClicked = dispatchOverlayTouch(event) } @@ -220,12 +224,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private fun toggleOverlayViewVisibility() { if (systemUiVisibility) { // we hide - TransitionManager.beginDelayedTransition(rootContainer) + TransitionManager.beginDelayedTransition(views.rootContainer) hideSystemUI() overlayView?.isVisible = false } else { // we show - TransitionManager.beginDelayedTransition(rootContainer) + TransitionManager.beginDelayedTransition(views.rootContainer) showSystemUI() overlayView?.isVisible = true } @@ -238,11 +242,11 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi return when (swipeDirection) { SwipeDirection.Up, SwipeDirection.Down -> { if (isSwipeToDismissAllowed && !wasScaled && isImagePagerIdle) { - swipeDismissHandler.onTouch(rootContainer, event) + swipeDismissHandler.onTouch(views.rootContainer, event) } else true } SwipeDirection.Left, SwipeDirection.Right -> { - attachmentPager.dispatchTouchEvent(event) + views.attachmentPager.dispatchTouchEvent(event) } else -> true } @@ -250,8 +254,8 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private fun handleSwipeViewMove(translationY: Float, translationLimit: Int) { val alpha = calculateTranslationAlpha(translationY, translationLimit) - backgroundView.alpha = alpha - dismissContainer.alpha = alpha + views.backgroundView.alpha = alpha + views.dismissContainer.alpha = alpha overlayView?.alpha = alpha } @@ -265,7 +269,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi private fun createSwipeToDismissHandler() : SwipeToDismissHandler = SwipeToDismissHandler( - swipeView = dismissContainer, + swipeView = views.dismissContainer, shouldAnimateDismiss = { shouldAnimateDismiss() }, onDismiss = { animateClose() }, onSwipeViewMove = ::handleSwipeViewMove) diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 519b8439c9..d72e5bda41 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' -apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-parcelize' apply plugin: 'realm-android' buildscript { @@ -13,10 +13,6 @@ buildscript { } } -androidExtensions { - experimental = true -} - android { compileSdkVersion 29 testOptions.unitTests.includeAndroidResources = true diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt index d89607843f..6759c59237 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SsoIdentityProvider.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.auth.data import android.os.Parcelable import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @JsonClass(generateAdapter = true) @Parcelize diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt index 4164b84ecd..98a84b8b66 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentAttachmentData.kt @@ -20,7 +20,7 @@ import android.net.Uri import android.os.Parcelable import androidx.exifinterface.media.ExifInterface import com.squareup.moshi.JsonClass -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.util.MimeTypes.normalizeMimeType @Parcelize diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt index 1e18887008..5d119bb617 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.auth.registration import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize /** * This class represent a localized privacy policy for registration Flow. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt index b77006aa3a..c071384df4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.attachments import android.os.Parcelable import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? { // Check the validity of some fields diff --git a/multipicker/build.gradle b/multipicker/build.gradle index 7c29a5539f..c58c4586b2 100644 --- a/multipicker/build.gradle +++ b/multipicker/build.gradle @@ -16,7 +16,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-parcelize' android { compileSdkVersion 29 diff --git a/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl b/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl index 7e6eac65c8..403d4bce1c 100644 --- a/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl +++ b/tools/templates/ElementFeature/root/src/app_package/Fragment.kt.ftl @@ -3,7 +3,7 @@ package ${escapeKotlinIdentifiers(packageName)} import android.os.Bundle <#if createFragmentArgs> import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import com.airbnb.mvrx.args import android.view.View diff --git a/vector/build.gradle b/vector/build.gradle index f526e31b60..ce2d9f4c97 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -3,17 +3,13 @@ import com.android.build.OutputFile apply plugin: 'com.android.application' apply plugin: 'com.google.android.gms.oss-licenses-plugin' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-kapt' kapt { correctErrorTypes = true } -androidExtensions { - experimental = true -} - // Note: 2 digits max for each value ext.versionMajor = 1 ext.versionMinor = 0 @@ -280,6 +276,10 @@ android { java.srcDirs += "src/sharedTest/java" } } + + buildFeatures { + viewBinding true + } } dependencies { diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt index 6c4bb925dd..fb87ba6299 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMaterialThemeActivity.kt @@ -24,7 +24,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.snackbar.Snackbar import im.vector.app.R import im.vector.app.core.utils.toast -import kotlinx.android.synthetic.debug.activity_test_material_theme.* + // Rendering is not the same with VectorBaseActivity abstract class DebugMaterialThemeActivity : AppCompatActivity() { diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index 1d9de30a0f..6700e7f5e6 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -21,6 +21,7 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.content.Intent import android.os.Build +import android.view.LayoutInflater import androidx.core.app.NotificationCompat import androidx.core.app.Person import androidx.core.content.getSystemService @@ -34,16 +35,17 @@ import im.vector.app.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA import im.vector.app.core.utils.allGranted import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.toast +import im.vector.app.databinding.ActivityDebugMenuBinding import im.vector.app.features.debug.sas.DebugSasEmojiActivity import im.vector.app.features.qrcode.QrCodeScannerActivity import org.matrix.android.sdk.internal.crypto.verification.qrcode.toQrCodeData -import kotlinx.android.synthetic.debug.activity_debug_menu.* + import timber.log.Timber import javax.inject.Inject -class DebugMenuActivity : VectorBaseActivity() { +class DebugMenuActivity : VectorBaseActivity() { - override fun getLayoutRes() = R.layout.activity_debug_menu + override fun getBinding() = ActivityDebugMenuBinding.inflate(layoutInflater) @Inject lateinit var activeSessionHolder: ActiveSessionHolder @@ -69,17 +71,17 @@ class DebugMenuActivity : VectorBaseActivity() { } private fun setupViews() { - debug_test_text_view_link.setOnClickListener { testTextViewLink() } - debug_show_sas_emoji.setOnClickListener { showSasEmoji() } - debug_test_notification.setOnClickListener { testNotification() } - debug_test_material_theme_light.setOnClickListener { testMaterialThemeLight() } - debug_test_material_theme_dark.setOnClickListener { testMaterialThemeDark() } - debug_test_crash.setOnClickListener { testCrash() } - debug_scan_qr_code.setOnClickListener { scanQRCode() } + views.debugTestTextViewLink.setOnClickListener { testTextViewLink() } + views.debugShowSasEmoji.setOnClickListener { showSasEmoji() } + views.debugTestNotification.setOnClickListener { testNotification() } + views.debugTestMaterialThemeLight.setOnClickListener { testMaterialThemeLight() } + views.debugTestMaterialThemeDark.setOnClickListener { testMaterialThemeDark() } + views.debugTestCrash.setOnClickListener { testCrash() } + views.debugScanQrCode.setOnClickListener { scanQRCode() } } private fun renderQrCode(text: String) { - debug_qr_code.setData(text) + views.debugQrCode.setData(text) } private fun testTextViewLink() { diff --git a/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt index 8b7a431435..ce1deef104 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/TestLinkifyActivity.kt @@ -22,7 +22,7 @@ import android.view.ViewGroup import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import im.vector.app.R -import kotlinx.android.synthetic.debug.activity_test_linkify.* + class TestLinkifyActivity : AppCompatActivity() { diff --git a/vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt index 869058eff6..7871fa0971 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/sas/DebugSasEmojiActivity.kt @@ -22,7 +22,7 @@ import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import org.matrix.android.sdk.api.crypto.getAllVerificationEmojis -import kotlinx.android.synthetic.main.fragment_generic_recycler.* + class DebugSasEmojiActivity : AppCompatActivity() { @@ -30,12 +30,12 @@ class DebugSasEmojiActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.fragment_generic_recycler) val controller = SasEmojiController() - genericRecyclerView.configureWith(controller) + views.genericRecyclerView.configureWith(controller) controller.setData(SasState(getAllVerificationEmojis())) } override fun onDestroy() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroy() } } diff --git a/vector/src/main/java/im/vector/app/core/dialogs/ConfirmationDialogBuilder.kt b/vector/src/main/java/im/vector/app/core/dialogs/ConfirmationDialogBuilder.kt index 0d9fb9d93d..ca1e9a2a2d 100644 --- a/vector/src/main/java/im/vector/app/core/dialogs/ConfirmationDialogBuilder.kt +++ b/vector/src/main/java/im/vector/app/core/dialogs/ConfirmationDialogBuilder.kt @@ -21,7 +21,7 @@ import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import im.vector.app.R -import kotlinx.android.synthetic.main.dialog_confirmation_with_reason.view.* + object ConfirmationDialogBuilder { diff --git a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt index 53c2b7fc6c..ef191d5110 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Activity.kt @@ -31,7 +31,7 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult) return registerForActivityResult(ActivityResultContracts.StartActivityForResult(), onResult) } -fun VectorBaseActivity.addFragment( +fun VectorBaseActivity<*>.addFragment( frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false @@ -39,7 +39,7 @@ fun VectorBaseActivity.addFragment( supportFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) } } -fun VectorBaseActivity.addFragment( +fun VectorBaseActivity<*>.addFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -51,7 +51,7 @@ fun VectorBaseActivity.addFragment( } } -fun VectorBaseActivity.replaceFragment( +fun VectorBaseActivity<*>.replaceFragment( frameId: Int, fragment: Fragment, tag: String? = null, @@ -60,7 +60,7 @@ fun VectorBaseActivity.replaceFragment( supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) } } -fun VectorBaseActivity.replaceFragment( +fun VectorBaseActivity<*>.replaceFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -72,7 +72,7 @@ fun VectorBaseActivity.replaceFragment( } } -fun VectorBaseActivity.addFragmentToBackstack( +fun VectorBaseActivity<*>.addFragmentToBackstack( frameId: Int, fragment: Fragment, tag: String? = null, @@ -81,19 +81,19 @@ fun VectorBaseActivity.addFragmentToBackstack( supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) } } -fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, - fragmentClass: Class, - params: Parcelable? = null, - tag: String? = null, - allowStateLoss: Boolean = false, - option: ((FragmentTransaction) -> Unit)? = null) { +fun VectorBaseActivity<*>.addFragmentToBackstack(frameId: Int, + fragmentClass: Class, + params: Parcelable? = null, + tag: String? = null, + allowStateLoss: Boolean = false, + option: ((FragmentTransaction) -> Unit)? = null) { supportFragmentManager.commitTransaction(allowStateLoss) { option?.invoke(this) replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } -fun VectorBaseActivity.hideKeyboard() { +fun VectorBaseActivity<*>.hideKeyboard() { currentFocus?.hideKeyboard() } diff --git a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt index 2740d5393a..21760da7ed 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Fragment.kt @@ -23,6 +23,7 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.fragment.app.Fragment +import com.airbnb.mvrx.BaseMvRxFragment import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.selectTxtFileToWrite @@ -34,7 +35,7 @@ fun Fragment.registerStartForActivityResult(onResult: (ActivityResult) -> Unit): return registerForActivityResult(ActivityResultContracts.StartActivityForResult(), onResult) } -fun VectorBaseFragment.addFragment( +fun Fragment.addFragment( frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false @@ -42,7 +43,7 @@ fun VectorBaseFragment.addFragment( parentFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) } } -fun VectorBaseFragment.addFragment( +fun VectorBaseFragment<*>.addFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -54,7 +55,7 @@ fun VectorBaseFragment.addFragment( } } -fun VectorBaseFragment.replaceFragment( +fun Fragment.replaceFragment( frameId: Int, fragment: Fragment, allowStateLoss: Boolean = false @@ -62,7 +63,7 @@ fun VectorBaseFragment.replaceFragment( parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment) } } -fun VectorBaseFragment.replaceFragment( +fun VectorBaseFragment<*>.replaceFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -74,7 +75,7 @@ fun VectorBaseFragment.replaceFragment( } } -fun VectorBaseFragment.addFragmentToBackstack( +fun Fragment.addFragmentToBackstack( frameId: Int, fragment: Fragment, tag: String? = null, @@ -83,7 +84,7 @@ fun VectorBaseFragment.addFragmentToBackstack( parentFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag).addToBackStack(tag) } } -fun VectorBaseFragment.addFragmentToBackstack( +fun VectorBaseFragment<*>.addFragmentToBackstack( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -95,7 +96,7 @@ fun VectorBaseFragment.addFragmentToBackstack( } } -fun VectorBaseFragment.addChildFragment( +fun Fragment.addChildFragment( frameId: Int, fragment: Fragment, tag: String? = null, @@ -104,7 +105,7 @@ fun VectorBaseFragment.addChildFragment( childFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment, tag) } } -fun VectorBaseFragment.addChildFragment( +fun VectorBaseFragment<*>.addChildFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -116,7 +117,7 @@ fun VectorBaseFragment.addChildFragment( } } -fun VectorBaseFragment.replaceChildFragment( +fun Fragment.replaceChildFragment( frameId: Int, fragment: Fragment, tag: String? = null, @@ -125,7 +126,7 @@ fun VectorBaseFragment.replaceChildFragment( childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) } } -fun VectorBaseFragment.replaceChildFragment( +fun VectorBaseFragment<*>.replaceChildFragment( frameId: Int, fragmentClass: Class, params: Parcelable? = null, @@ -137,7 +138,7 @@ fun VectorBaseFragment.replaceChildFragment( } } -fun VectorBaseFragment.addChildFragmentToBackstack( +fun Fragment.addChildFragmentToBackstack( frameId: Int, fragment: Fragment, tag: String? = null, @@ -146,7 +147,7 @@ fun VectorBaseFragment.addChildFragmentToBackstack( childFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) } } -fun VectorBaseFragment.addChildFragmentToBackstack( +fun VectorBaseFragment<*>.addChildFragmentToBackstack( frameId: Int, fragmentClass: Class, params: Parcelable? = null, diff --git a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt index cb05a2ac7d..254723a282 100755 --- a/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/ButtonStateView.kt @@ -25,7 +25,7 @@ import android.widget.FrameLayout import androidx.core.view.isInvisible import androidx.core.view.isVisible import im.vector.app.R -import kotlinx.android.synthetic.main.view_button_state.view.* + class ButtonStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : FrameLayout(context, attrs, defStyle) { diff --git a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt index 76baf347f9..8574073f39 100644 --- a/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/SimpleFragmentActivity.kt @@ -15,23 +15,24 @@ */ package im.vector.app.core.platform +import android.view.LayoutInflater import androidx.annotation.CallSuper import androidx.core.view.isGone import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.hideKeyboard -import kotlinx.android.synthetic.main.activity.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import im.vector.app.databinding.ActivityBinding + import org.matrix.android.sdk.api.session.Session import javax.inject.Inject /** * Simple activity with a toolbar, a waiting overlay, and a fragment container and a session. */ -abstract class SimpleFragmentActivity : VectorBaseActivity() { +abstract class SimpleFragmentActivity : VectorBaseActivity() { - override fun getLayoutRes() = R.layout.activity + override fun getBinding() = ActivityBinding.inflate(layoutInflater) @Inject lateinit var session: Session @@ -41,8 +42,8 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() { } override fun initUiAndData() { - configureToolbar(toolbar) - waitingView = findViewById(R.id.waiting_view) + configureToolbar(views.toolbar) + waitingView = views.overlayWaitingView.waitingView } /** @@ -51,21 +52,21 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() { */ fun updateWaitingView(data: WaitingViewData?) { data?.let { - waitingStatusText.text = data.message + views.overlayWaitingView.waitingStatusText.text = data.message if (data.progress != null && data.progressTotal != null) { - waitingHorizontalProgress.isIndeterminate = false - waitingHorizontalProgress.progress = data.progress - waitingHorizontalProgress.max = data.progressTotal - waitingHorizontalProgress.isVisible = true - waitingCircularProgress.isVisible = false + views.overlayWaitingView.waitingHorizontalProgress.isIndeterminate = false + views.overlayWaitingView.waitingHorizontalProgress.progress = data.progress + views.overlayWaitingView.waitingHorizontalProgress.max = data.progressTotal + views.overlayWaitingView.waitingHorizontalProgress.isVisible = true + views.overlayWaitingView.waitingCircularProgress.isVisible = false } else if (data.isIndeterminate) { - waitingHorizontalProgress.isIndeterminate = true - waitingHorizontalProgress.isVisible = true - waitingCircularProgress.isVisible = false + views.overlayWaitingView.waitingHorizontalProgress.isIndeterminate = true + views.overlayWaitingView.waitingHorizontalProgress.isVisible = true + views.overlayWaitingView.waitingCircularProgress.isVisible = false } else { - waitingHorizontalProgress.isVisible = false - waitingCircularProgress.isVisible = true + views.overlayWaitingView.waitingHorizontalProgress.isVisible = false + views.overlayWaitingView.waitingCircularProgress.isVisible = true } showWaitingView() @@ -76,15 +77,15 @@ abstract class SimpleFragmentActivity : VectorBaseActivity() { override fun showWaitingView() { hideKeyboard() - waitingStatusText.isGone = waitingStatusText.text.isNullOrBlank() + views.overlayWaitingView.waitingStatusText.isGone = views.overlayWaitingView.waitingStatusText.text.isNullOrBlank() super.showWaitingView() } override fun hideWaitingView() { - waitingStatusText.text = null - waitingStatusText.isGone = true - waitingHorizontalProgress.progress = 0 - waitingHorizontalProgress.isVisible = false + views.overlayWaitingView.waitingStatusText.text = null + views.overlayWaitingView.waitingStatusText.isGone = true + views.overlayWaitingView.waitingHorizontalProgress.progress = 0 + views.overlayWaitingView.waitingHorizontalProgress.isVisible = false super.hideWaitingView() } diff --git a/vector/src/main/java/im/vector/app/core/platform/StateView.kt b/vector/src/main/java/im/vector/app/core/platform/StateView.kt index 57f5a11a91..f753b640a0 100755 --- a/vector/src/main/java/im/vector/app/core/platform/StateView.kt +++ b/vector/src/main/java/im/vector/app/core/platform/StateView.kt @@ -24,7 +24,7 @@ import android.widget.FrameLayout import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.extensions.updateConstraintSet -import kotlinx.android.synthetic.main.view_state.view.* + class StateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : FrameLayout(context, attrs, defStyle) { diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 4006137ee9..56ac8d4078 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -21,24 +21,26 @@ import android.content.Context import android.content.res.Configuration import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View import android.view.WindowManager import androidx.annotation.AttrRes import androidx.annotation.CallSuper -import androidx.annotation.LayoutRes import androidx.annotation.MainThread import androidx.annotation.MenuRes import androidx.annotation.StringRes import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar +import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentFactory import androidx.fragment.app.FragmentManager import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider +import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MvRx import com.bumptech.glide.util.Util import com.google.android.material.snackbar.Snackbar @@ -79,13 +81,19 @@ import im.vector.app.receivers.DebugReceiver import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable -import kotlinx.android.synthetic.main.activity.* + import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber import kotlin.system.measureTimeMillis -abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { +abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { + /* ========================================================================================== + * View + * ========================================================================================== */ + + protected lateinit var views: VB + /* ========================================================================================== * View model * ========================================================================================== */ @@ -210,9 +218,8 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { // Hack for font size applyFontSize() - if (getLayoutRes() != -1) { - setContentView(getLayoutRes()) - } + views = getBinding() + setContentView(views.root) this.savedInstanceState = savedInstanceState @@ -450,7 +457,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { } private fun recursivelyDispatchOnBackPressed(fm: FragmentManager, fromToolbar: Boolean): Boolean { - val reverseOrder = fm.fragments.filterIsInstance().reversed() + val reverseOrder = fm.fragments.filterIsInstance>().reversed() for (f in reverseOrder) { val handledByChildFragments = recursivelyDispatchOnBackPressed(f.childFragmentManager, fromToolbar) if (handledByChildFragments) { @@ -537,8 +544,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { * OPEN METHODS * ========================================================================================== */ - @LayoutRes - open fun getLayoutRes() = -1 + abstract fun getBinding(): VB open fun displayInFullscreen() = false @@ -565,13 +571,13 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { * ========================================================================================== */ fun showSnackbar(message: String) { - coordinatorLayout?.let { + getCoordinatorLayout()?.let { Snackbar.make(it, message, Snackbar.LENGTH_SHORT).show() } } fun showSnackbar(message: String, @StringRes withActionTitle: Int?, action: (() -> Unit)?) { - coordinatorLayout?.let { + getCoordinatorLayout()?.let { Snackbar.make(it, message, Snackbar.LENGTH_LONG).apply { withActionTitle?.let { setAction(withActionTitle, { action?.invoke() }) @@ -580,6 +586,9 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScreenInjector { } } + // TODO BMA Provide the CL from the Views + open fun getCoordinatorLayout(): CoordinatorLayout? = null + /* ========================================================================================== * User Consent * ========================================================================================== */ diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt index 74e9afb651..4190ff228f 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseBottomSheetDialogFragment.kt @@ -27,6 +27,7 @@ import android.widget.FrameLayout import androidx.annotation.CallSuper import androidx.annotation.LayoutRes import androidx.lifecycle.ViewModelProvider +import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRxView import com.airbnb.mvrx.MvRxViewId @@ -46,7 +47,7 @@ import java.util.concurrent.TimeUnit /** * Add MvRx capabilities to bottomsheetdialog (like BaseMvRxFragment) */ -abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MvRxView { +abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment(), MvRxView { private val mvrxViewIdProperty = MvRxViewId() final override val mvrxViewId: String by mvrxViewIdProperty @@ -56,8 +57,13 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() * View * ========================================================================================== */ - @LayoutRes - abstract fun getLayoutResId(): Int + private var _binding: VB? = null + + // This property is only valid between onCreateView and onDestroyView. + protected val views: VB + get() = _binding!! + + abstract fun getBinding(inflater: LayoutInflater, container: ViewGroup?): VB /* ========================================================================================== * View model @@ -77,8 +83,8 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() private var bottomSheetBehavior: BottomSheetBehavior? = null - val vectorBaseActivity: VectorBaseActivity by lazy { - activity as VectorBaseActivity + val vectorBaseActivity: VectorBaseActivity<*> by lazy { + activity as VectorBaseActivity<*> } open val showExpanded = false @@ -102,7 +108,8 @@ abstract class VectorBaseBottomSheetDialogFragment : BottomSheetDialogFragment() } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(getLayoutResId(), container, false) + _binding = getBinding(inflater, container) + return views.root } @CallSuper diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index ffaee5075f..7ca3469282 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -33,6 +33,7 @@ import androidx.annotation.MainThread import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.Toolbar import androidx.lifecycle.ViewModelProvider +import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.BaseMvRxFragment import com.airbnb.mvrx.MvRx import com.bumptech.glide.util.Util.assertMainThread @@ -48,14 +49,14 @@ import im.vector.app.features.navigation.Navigator import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.Disposable -import kotlinx.android.synthetic.main.activity.* + import timber.log.Timber import java.util.concurrent.TimeUnit -abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { +abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { - protected val vectorBaseActivity: VectorBaseActivity by lazy { - activity as VectorBaseActivity + protected val vectorBaseActivity: VectorBaseActivity<*> by lazy { + activity as VectorBaseActivity<*> } /* ========================================================================================== @@ -82,6 +83,16 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { protected val fragmentViewModelProvider get() = ViewModelProvider(this, viewModelFactory) + /* ========================================================================================== + * Views + * ========================================================================================== */ + + private var _binding: VB? = null + + // This property is only valid between onCreateView and onDestroyView. + protected val views: VB + get() = _binding!! + /* ========================================================================================== * Life cycle * ========================================================================================== */ @@ -106,11 +117,11 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { final override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { Timber.i("onCreateView Fragment ${javaClass.simpleName}") - return inflater.inflate(getLayoutResId(), container, false) + _binding = getBinding(inflater, container) + return views.root } - @LayoutRes - abstract fun getLayoutResId(): Int + abstract fun getBinding(inflater: LayoutInflater, container: ViewGroup?): VB @CallSuper override fun onResume() { @@ -137,6 +148,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { super.onDestroyView() Timber.i("onDestroyView Fragment ${javaClass.simpleName}") uiDisposables.clear() + _binding = null } override fun onDestroy() { @@ -174,6 +186,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { arguments = args.toMvRxBundle() } + // TODO BMA Extract this and use simple type in Fragment.kt fun Parcelable?.toMvRxBundle(): Bundle? { return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } } } @@ -186,7 +199,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector { } protected fun showErrorInSnackbar(throwable: Throwable) { - vectorBaseActivity.coordinatorLayout?.let { + vectorBaseActivity.getCoordinatorLayout()?.let { Snackbar.make(it, errorFormatter.toHumanReadable(throwable), Snackbar.LENGTH_SHORT) .show() } diff --git a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt index ab4a781aab..a2318e3608 100644 --- a/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt +++ b/vector/src/main/java/im/vector/app/core/ui/bottomsheet/BottomSheetGeneric.kt @@ -17,41 +17,47 @@ package im.vector.app.core.ui.bottomsheet import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.annotation.CallSuper import androidx.recyclerview.widget.RecyclerView import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject /** * Generic Bottom sheet with actions */ abstract class BottomSheetGeneric : - VectorBaseBottomSheetDialogFragment(), + VectorBaseBottomSheetDialogFragment(), BottomSheetGenericController.Listener { @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool final override val showExpanded = true - final override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + final override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } abstract fun getController(): BottomSheetGenericController @CallSuper override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.configureWith(getController(), viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) + views.views.bottomSheetRecyclerView.configureWith(getController(), viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) getController().listener = this } @CallSuper override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.views.bottomSheetRecyclerView.cleanup() getController().listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt b/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt index d418822b7f..7a09f394d3 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/BottomSheetActionButton.kt @@ -29,8 +29,6 @@ import androidx.core.content.withStyledAttributes import androidx.core.view.isGone import androidx.core.view.isInvisible import androidx.core.view.isVisible -import butterknife.BindView -import butterknife.ButterKnife import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.themes.ThemeUtils @@ -41,20 +39,11 @@ class BottomSheetActionButton @JvmOverloads constructor( defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr) { - @BindView(R.id.itemVerificationActionTitle) - lateinit var actionTextView: TextView - - @BindView(R.id.itemVerificationActionSubTitle) - lateinit var descriptionTextView: TextView - - @BindView(R.id.itemVerificationLeftIcon) - lateinit var leftIconImageView: ImageView - - @BindView(R.id.itemVerificationActionIcon) - lateinit var rightIconImageView: ImageView - - @BindView(R.id.itemVerificationClickableZone) - lateinit var clickableView: View + private val actionTextView: TextView + private val descriptionTextView: TextView + private val leftIconImageView: ImageView + private val rightIconImageView: ImageView + private val clickableView: View var title: String? = null set(value) { @@ -116,7 +105,12 @@ class BottomSheetActionButton @JvmOverloads constructor( init { inflate(context, R.layout.item_verification_action, this) - ButterKnife.bind(this) + + actionTextView = findViewById(R.id.itemVerificationActionTitle) + descriptionTextView = findViewById(R.id.itemVerificationActionSubTitle) + leftIconImageView = findViewById(R.id.itemVerificationLeftIcon) + rightIconImageView = findViewById(R.id.itemVerificationActionIcon) + clickableView = findViewById(R.id.itemVerificationClickableZone) context.withStyledAttributes(attrs, R.styleable.BottomSheetActionButton) { title = getString(R.styleable.BottomSheetActionButton_actionTitle) ?: "" diff --git a/vector/src/main/java/im/vector/app/core/ui/views/JumpToReadMarkerView.kt b/vector/src/main/java/im/vector/app/core/ui/views/JumpToReadMarkerView.kt index 3c48637e74..b305d3246e 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/JumpToReadMarkerView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/JumpToReadMarkerView.kt @@ -22,7 +22,7 @@ import android.view.View import android.widget.RelativeLayout import androidx.core.content.ContextCompat import im.vector.app.R -import kotlinx.android.synthetic.main.view_jump_to_read_marker.view.* + class JumpToReadMarkerView @JvmOverloads constructor( context: Context, diff --git a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt index c935d7662f..478f448e1d 100755 --- a/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/KeysBackupBanner.kt @@ -24,7 +24,7 @@ import androidx.core.content.edit import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.di.DefaultSharedPreferences -import kotlinx.android.synthetic.main.view_keys_backup_banner.view.* + import timber.log.Timber /** diff --git a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt index 4620d7a1fb..ca6ea52aab 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/NotificationAreaView.kt @@ -28,7 +28,7 @@ import im.vector.app.R import im.vector.app.core.error.ResourceLimitErrorFormatter import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.themes.ThemeUtils -import kotlinx.android.synthetic.main.view_notification_area.view.* + import me.gujun.android.span.span import me.saket.bettermovementmethod.BetterLinkMovementMethod import org.matrix.android.sdk.api.failure.MatrixError diff --git a/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt b/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt index 9d3ca6efba..508b28b306 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/PasswordStrengthBar.kt @@ -22,7 +22,7 @@ import android.widget.LinearLayout import androidx.annotation.IntRange import androidx.core.content.ContextCompat import im.vector.app.R -import kotlinx.android.synthetic.main.view_password_strength_bar.view.* + /** * A password strength bar custom widget diff --git a/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt b/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt index b1ef746ee7..f4d39e3198 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/ReadReceiptsView.kt @@ -26,7 +26,7 @@ import im.vector.app.R import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData import im.vector.app.features.home.room.detail.timeline.item.toMatrixItem -import kotlinx.android.synthetic.main.view_read_receipts.view.* + private const val MAX_RECEIPT_DISPLAYED = 5 private const val MAX_RECEIPT_DESCRIBED = 3 diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 8499b740f7..0a2bb9d039 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -20,6 +20,7 @@ import android.app.Activity import android.content.Intent import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import androidx.appcompat.app.AlertDialog import androidx.lifecycle.Lifecycle import com.bumptech.glide.Glide @@ -30,6 +31,7 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.startSyncing import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.deleteAllFiles +import im.vector.app.databinding.FragmentLoadingBinding import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.ShortcutsHandler import im.vector.app.features.login.LoginActivity @@ -42,7 +44,7 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.signout.hard.SignedOutActivity import im.vector.app.features.signout.soft.SoftLogoutActivity import im.vector.app.features.ui.UiStateRepository -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -66,7 +68,7 @@ data class MainActivityArgs( * This Activity, when started with argument, is also doing some cleanup when user signs out, * clears cache, is logged out, or is soft logged out */ -class MainActivity : VectorBaseActivity(), UnlockedActivity { +class MainActivity : VectorBaseActivity(), UnlockedActivity { companion object { private const val EXTRA_ARGS = "EXTRA_ARGS" @@ -83,6 +85,8 @@ class MainActivity : VectorBaseActivity(), UnlockedActivity { } } + override fun getBinding() = FragmentLoadingBinding.inflate(layoutInflater) + private lateinit var args: MainActivityArgs @Inject lateinit var notificationDrawerManager: NotificationDrawerManager diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt index 8e830d00a4..eec117bb40 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewActivity.kt @@ -19,15 +19,17 @@ package im.vector.app.features.attachments.preview import android.content.Context import android.content.Intent +import android.view.LayoutInflater import androidx.appcompat.widget.Toolbar import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.themes.ActivityOtherThemes import org.matrix.android.sdk.api.session.content.ContentAttachmentData -class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { +class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS" @@ -51,7 +53,7 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { override fun getOtherThemes() = ActivityOtherThemes.AttachmentsPreview - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun initUiAndData() { if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt index f67b0946cc..7b560481cd 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/preview/AttachmentsPreviewFragment.kt @@ -21,6 +21,7 @@ import android.app.Activity.RESULT_CANCELED import android.app.Activity.RESULT_OK import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View @@ -45,9 +46,10 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.OnSnapPositionChangeListener import im.vector.app.core.utils.SnapOnScrollListener import im.vector.app.core.utils.attachSnapHelperWithListener +import im.vector.app.databinding.FragmentAttachmentsPreviewBinding import im.vector.app.features.media.createUCropWithDefaultSettings -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_attachments_preview.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.content.ContentAttachmentData import java.io.File @@ -62,19 +64,21 @@ class AttachmentsPreviewFragment @Inject constructor( private val attachmentMiniaturePreviewController: AttachmentMiniaturePreviewController, private val attachmentBigPreviewController: AttachmentBigPreviewController, private val colorProvider: ColorProvider -) : VectorBaseFragment(), AttachmentMiniaturePreviewController.Callback { +) : VectorBaseFragment(), AttachmentMiniaturePreviewController.Callback { private val fragmentArgs: AttachmentsPreviewArgs by args() private val viewModel: AttachmentsPreviewViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_attachments_preview + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentAttachmentsPreviewBinding { + return FragmentAttachmentsPreviewBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) applyInsets() setupRecyclerViews() - setupToolbar(attachmentPreviewerToolbar) - attachmentPreviewerSendButton.setOnClickListener { + setupToolbar(views.attachmentPreviewerToolbar) + views.attachmentPreviewerSendButton.setOnClickListener { setResultAndFinish() } } @@ -120,8 +124,8 @@ class AttachmentsPreviewFragment @Inject constructor( override fun onDestroyView() { super.onDestroyView() - attachmentPreviewerMiniatureList.cleanup() - attachmentPreviewerBigList.cleanup() + views.attachmentPreviewerMiniatureList.cleanup() + views.attachmentPreviewerBigList.cleanup() attachmentMiniaturePreviewController.callback = null } @@ -133,9 +137,9 @@ class AttachmentsPreviewFragment @Inject constructor( } else { attachmentMiniaturePreviewController.setData(state) attachmentBigPreviewController.setData(state) - attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex) - attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex) - attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size) + views.attachmentPreviewerBigList.scrollToPosition(state.currentAttachmentIndex) + views.attachmentPreviewerMiniatureList.scrollToPosition(state.currentAttachmentIndex) + views.attachmentPreviewerSendImageOriginalSize.text = resources.getQuantityString(R.plurals.send_images_with_original_size, state.attachments.size) } } @@ -146,17 +150,17 @@ class AttachmentsPreviewFragment @Inject constructor( private fun setResultAndFinish() = withState(viewModel) { (requireActivity() as? AttachmentsPreviewActivity)?.setResultAndFinish( it.attachments, - attachmentPreviewerSendImageOriginalSize.isChecked + views.attachmentPreviewerSendImageOriginalSize.isChecked ) } private fun applyInsets() { view?.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - ViewCompat.setOnApplyWindowInsetsListener(attachmentPreviewerBottomContainer) { v, insets -> + ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerBottomContainer) { v, insets -> v.updatePadding(bottom = insets.systemWindowInsetBottom) insets } - ViewCompat.setOnApplyWindowInsetsListener(attachmentPreviewerToolbar) { v, insets -> + ViewCompat.setOnApplyWindowInsetsListener(views.attachmentPreviewerToolbar) { v, insets -> v.updateLayoutParams { topMargin = insets.systemWindowInsetTop } @@ -180,13 +184,13 @@ class AttachmentsPreviewFragment @Inject constructor( private fun setupRecyclerViews() { attachmentMiniaturePreviewController.callback = this - attachmentPreviewerMiniatureList.let { + views.attachmentPreviewerMiniatureList.let { it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) it.setHasFixedSize(true) it.adapter = attachmentMiniaturePreviewController.adapter } - attachmentPreviewerBigList.let { + views.attachmentPreviewerBigList.let { it.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) it.attachSnapHelperWithListener( PagerSnapHelper(), diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt index b1a2c65ecf..7646da9516 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallControlsBottomSheet.kt @@ -17,18 +17,24 @@ package im.vector.app.features.call import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.view.isVisible import com.airbnb.mvrx.activityViewModel import im.vector.app.R import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import kotlinx.android.synthetic.main.bottom_sheet_call_controls.* +import im.vector.app.databinding.BottomSheetCallControlsBinding +import im.vector.app.databinding.BottomSheetGenericListBinding + import me.gujun.android.span.span -class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() { - override fun getLayoutResId() = R.layout.bottom_sheet_call_controls +class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() { + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetCallControlsBinding { + return BottomSheetCallControlsBinding.inflate(inflater, container, false) + } private val callViewModel: VectorCallViewModel by activityViewModel() @@ -39,16 +45,16 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() { renderState(it) } - callControlsSoundDevice.clickableView.debouncedClicks { + views.callControlsSoundDevice.clickableView.debouncedClicks { callViewModel.handle(VectorCallViewActions.SwitchSoundDevice) } - callControlsSwitchCamera.clickableView.debouncedClicks { + views.callControlsSwitchCamera.clickableView.debouncedClicks { callViewModel.handle(VectorCallViewActions.ToggleCamera) dismiss() } - callControlsToggleSDHD.clickableView.debouncedClicks { + views.callControlsToggleSDHD.clickableView.debouncedClicks { callViewModel.handle(VectorCallViewActions.ToggleHDSD) dismiss() } @@ -109,30 +115,30 @@ class CallControlsBottomSheet : VectorBaseBottomSheetDialogFragment() { } private fun renderState(state: VectorCallViewState) { - callControlsSoundDevice.title = getString(R.string.call_select_sound_device) - callControlsSoundDevice.subTitle = when (state.soundDevice) { + views.callControlsSoundDevice.title = getString(R.string.call_select_sound_device) + views.callControlsSoundDevice.subTitle = when (state.soundDevice) { CallAudioManager.SoundDevice.PHONE -> getString(R.string.sound_device_phone) CallAudioManager.SoundDevice.SPEAKER -> getString(R.string.sound_device_speaker) CallAudioManager.SoundDevice.HEADSET -> getString(R.string.sound_device_headset) CallAudioManager.SoundDevice.WIRELESS_HEADSET -> getString(R.string.sound_device_wireless_headset) } - callControlsSwitchCamera.isVisible = state.isVideoCall && state.canSwitchCamera - callControlsSwitchCamera.subTitle = getString(if (state.isFrontCamera) R.string.call_camera_front else R.string.call_camera_back) + views.callControlsSwitchCamera.isVisible = state.isVideoCall && state.canSwitchCamera + views.callControlsSwitchCamera.subTitle = getString(if (state.isFrontCamera) R.string.call_camera_front else R.string.call_camera_back) if (state.isVideoCall) { - callControlsToggleSDHD.isVisible = true + views.callControlsToggleSDHD.isVisible = true if (state.isHD) { - callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_off) - callControlsToggleSDHD.subTitle = null - callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd_disabled) + views.callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_off) + views.callControlsToggleSDHD.subTitle = null + views.callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd_disabled) } else { - callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_on) - callControlsToggleSDHD.subTitle = null - callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd) + views.callControlsToggleSDHD.title = getString(R.string.call_format_turn_hd_on) + views.callControlsToggleSDHD.subTitle = null + views.callControlsToggleSDHD.leftIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_hd) } } else { - callControlsToggleSDHD.isVisible = false + views.callControlsToggleSDHD.isVisible = false } } } diff --git a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt index 81cc077f03..9b36042ff4 100644 --- a/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt +++ b/vector/src/main/java/im/vector/app/features/call/CallControlsView.kt @@ -18,11 +18,13 @@ package im.vector.app.features.call import android.content.Context import android.util.AttributeSet +import android.view.View +import android.widget.ImageView import android.widget.LinearLayout import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible import im.vector.app.R -import kotlinx.android.synthetic.main.view_call_controls.view.* + import org.matrix.android.sdk.api.session.call.CallState import org.webrtc.PeerConnection @@ -30,19 +32,40 @@ class CallControlsView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : LinearLayout(context, attrs, defStyleAttr) { + private var ringingControls: View + private var connectedControls: View + + private val ringingControlAccept: View + private var ringingControlDecline: View + private var iv_end_call: View + private var muteIcon: ImageView + private var videoToggleIcon: ImageView + private var iv_leftMiniControl: View + private var iv_more: View + var interactionListener: InteractionListener? = null init { - ConstraintLayout.inflate(context, R.layout.view_call_controls, this) + View.inflate(context, R.layout.view_call_controls, this) // layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) - ringingControlAccept.setOnClickListener { acceptIncomingCall() } - ringingControlDecline.setOnClickListener { declineIncomingCall() } - iv_end_call.setOnClickListener { endOngoingCall() } - muteIcon.setOnClickListener { toggleMute() } - videoToggleIcon.setOnClickListener { toggleVideo() } - iv_leftMiniControl.setOnClickListener { returnToChat() } - iv_more.setOnClickListener { moreControlOption() } + ringingControlAccept = findViewById(R.id.ringingControlAccept) + .also { it.setOnClickListener { acceptIncomingCall() } } + ringingControlDecline = findViewById(R.id.ringingControlDecline) + .also { it.setOnClickListener { declineIncomingCall() } } + iv_end_call = findViewById(R.id.iv_end_call) + .also { it.setOnClickListener { endOngoingCall() } } + muteIcon = findViewById(R.id.muteIcon) + .also { it.setOnClickListener { toggleMute() } } + videoToggleIcon = findViewById(R.id.videoToggleIcon) + .also { it.setOnClickListener { toggleVideo() } } + iv_leftMiniControl = findViewById(R.id.iv_leftMiniControl) + .also { it.setOnClickListener { returnToChat() } } + iv_more = findViewById(R.id.iv_more) + .also { it.setOnClickListener { moreControlOption() } } + + ringingControls = findViewById(R.id.ringingControls) + connectedControls = findViewById(R.id.connectedControls) } private fun acceptIncomingCall() { diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt index aee882fedf..254a9fa017 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallActivity.kt @@ -23,6 +23,7 @@ import android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP import android.os.Build import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View import android.view.Window import android.view.WindowManager @@ -44,12 +45,13 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_AUDIO_IP_CALL import im.vector.app.core.utils.PERMISSIONS_FOR_VIDEO_IP_CALL import im.vector.app.core.utils.allGranted import im.vector.app.core.utils.checkPermissions +import im.vector.app.databinding.ActivityCallBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailArgs import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity_call.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.session.call.CallState import org.matrix.android.sdk.api.session.call.EglUtils import org.matrix.android.sdk.api.session.call.MxCallDetail @@ -70,9 +72,9 @@ data class CallArgs( val isVideoCall: Boolean ) : Parcelable -class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionListener { +class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionListener { - override fun getLayoutRes() = R.layout.activity_call + override fun getBinding() = ActivityCallBinding.inflate(layoutInflater) @Inject lateinit var avatarRenderer: AvatarRenderer @@ -147,7 +149,7 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis super.onCreate(savedInstanceState) // This will need to be refined - ViewCompat.setOnApplyWindowInsetsListener(constraintLayout) { v, insets -> + ViewCompat.setOnApplyWindowInsetsListener(views.constraintLayout) { v, insets -> v.updatePadding(bottom = if (systemUiVisibility) insets.systemWindowInsetBottom else 0) insets } @@ -167,7 +169,7 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis turnScreenOnAndKeyguardOff() } - constraintLayout.clicks() + views.constraintLayout.clicks() .throttleFirst(300, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe { toggleUiSystemVisibility() } @@ -199,10 +201,10 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis } override fun onDestroy() { - peerConnectionManager.detachRenderers(listOf(pipRenderer, fullscreenRenderer)) + peerConnectionManager.detachRenderers(listOf(views.pipRenderer, views.fullscreenRenderer)) if (surfaceRenderersAreInitialized) { - pipRenderer.release() - fullscreenRenderer.release() + views.pipRenderer.release() + views.fullscreenRenderer.release() } turnScreenOffAndKeyguardOn() super.onDestroy() @@ -217,54 +219,54 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis return } - callControlsView.updateForState(state) + views.callControlsView.updateForState(state) val callState = state.callState.invoke() - callConnectingProgress.isVisible = false + views.callConnectingProgress.isVisible = false when (callState) { is CallState.Idle, is CallState.Dialing -> { - callVideoGroup.isInvisible = true - callInfoGroup.isVisible = true - callStatusText.setText(R.string.call_ring) + views.callVideoGroup.isInvisible = true + views.callInfoGroup.isVisible = true + views.callStatusText.setText(R.string.call_ring) configureCallInfo(state) } is CallState.LocalRinging -> { - callVideoGroup.isInvisible = true - callInfoGroup.isVisible = true - callStatusText.text = null + views.callVideoGroup.isInvisible = true + views.callInfoGroup.isVisible = true + views.callStatusText.text = null configureCallInfo(state) } is CallState.Answering -> { - callVideoGroup.isInvisible = true - callInfoGroup.isVisible = true - callStatusText.setText(R.string.call_connecting) - callConnectingProgress.isVisible = true + views.callVideoGroup.isInvisible = true + views.callInfoGroup.isVisible = true + views.callStatusText.setText(R.string.call_connecting) + views.callConnectingProgress.isVisible = true configureCallInfo(state) } is CallState.Connected -> { if (callState.iceConnectionState == PeerConnection.PeerConnectionState.CONNECTED) { if (callArgs.isVideoCall) { - callVideoGroup.isVisible = true - callInfoGroup.isVisible = false - pipRenderer.isVisible = !state.isVideoCaptureInError + views.callVideoGroup.isVisible = true + views.callInfoGroup.isVisible = false + views.pipRenderer.isVisible = !state.isVideoCaptureInError } else { - callVideoGroup.isInvisible = true - callInfoGroup.isVisible = true + views.callVideoGroup.isInvisible = true + views.callInfoGroup.isVisible = true configureCallInfo(state) - callStatusText.text = null + views.callStatusText.text = null } } else { // This state is not final, if you change network, new candidates will be sent - callVideoGroup.isInvisible = true - callInfoGroup.isVisible = true + views.callVideoGroup.isInvisible = true + views.callInfoGroup.isVisible = true configureCallInfo(state) - callStatusText.setText(R.string.call_connecting) - callConnectingProgress.isVisible = true + views.callStatusText.setText(R.string.call_connecting) + views.callConnectingProgress.isVisible = true } // ensure all attached? - peerConnectionManager.attachViewRenderers(pipRenderer, fullscreenRenderer, null) + peerConnectionManager.attachViewRenderers(views.pipRenderer, views.fullscreenRenderer, null) } is CallState.Terminated -> { finish() @@ -276,14 +278,14 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis private fun configureCallInfo(state: VectorCallViewState) { state.otherUserMatrixItem.invoke()?.let { - avatarRenderer.render(it, otherMemberAvatar) - participantNameText.text = it.getBestName() - callTypeText.setText(if (state.isVideoCall) R.string.action_video_call else R.string.action_voice_call) + avatarRenderer.render(it, views.otherMemberAvatar) + views.participantNameText.text = it.getBestName() + views.callTypeText.setText(if (state.isVideoCall) R.string.action_video_call else R.string.action_voice_call) } } private fun configureCallViews() { - callControlsView.interactionListener = this + views.callControlsView.interactionListener = this } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { @@ -303,21 +305,24 @@ class VectorCallActivity : VectorBaseActivity(), CallControlsView.InteractionLis } // Init Picture in Picture renderer - pipRenderer.init(rootEglBase!!.eglBaseContext, null) - pipRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) + views.pipRenderer.init(rootEglBase!!.eglBaseContext, null) + views.pipRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) // Init Full Screen renderer - fullscreenRenderer.init(rootEglBase!!.eglBaseContext, null) - fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) + views.fullscreenRenderer.init(rootEglBase!!.eglBaseContext, null) + views.fullscreenRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT) - pipRenderer.setZOrderMediaOverlay(true) - pipRenderer.setEnableHardwareScaler(true /* enabled */) - fullscreenRenderer.setEnableHardwareScaler(true /* enabled */) + views.pipRenderer.setZOrderMediaOverlay(true) + views.pipRenderer.setEnableHardwareScaler(true /* enabled */) + views.fullscreenRenderer.setEnableHardwareScaler(true /* enabled */) - peerConnectionManager.attachViewRenderers(pipRenderer, fullscreenRenderer, - intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() }) + peerConnectionManager.attachViewRenderers( + views.pipRenderer, + views.fullscreenRenderer, + intent.getStringExtra(EXTRA_MODE)?.takeIf { isFirstCreation() } + ) - pipRenderer.setOnClickListener { + views.pipRenderer.setOnClickListener { callViewModel.handle(VectorCallViewActions.ToggleCamera) } surfaceRenderersAreInitialized = true diff --git a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt index 43b41f7b5a..478cc676db 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/VectorJitsiActivity.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.Intent import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View import android.widget.FrameLayout import androidx.core.view.isVisible @@ -31,8 +32,9 @@ import com.facebook.react.modules.core.PermissionListener import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity_jitsi.* +import im.vector.app.databinding.ActivityJitsiBinding +import kotlinx.parcelize.Parcelize + import org.jitsi.meet.sdk.JitsiMeetActivityDelegate import org.jitsi.meet.sdk.JitsiMeetActivityInterface import org.jitsi.meet.sdk.JitsiMeetConferenceOptions @@ -42,7 +44,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull import java.net.URL import javax.inject.Inject -class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, JitsiMeetViewListener { +class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, JitsiMeetViewListener { @Parcelize data class Args( @@ -51,7 +53,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, Ji val enableVideo: Boolean ) : Parcelable - override fun getLayoutRes() = R.layout.activity_jitsi + override fun getBinding() = ActivityJitsiBinding.inflate(layoutInflater) @Inject lateinit var viewModelFactory: JitsiCallViewModel.Factory @@ -76,7 +78,7 @@ class VectorJitsiActivity : VectorBaseActivity(), JitsiMeetActivityInterface, Ji super.initUiAndData() jitsiMeetView = JitsiMeetView(this) val params = FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT) - jitsi_layout.addView(jitsiMeetView, params) + views.jitsiLayout.addView(jitsiMeetView, params) jitsiMeetView?.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt index 6c3ec06f75..a99275d439 100644 --- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt +++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.contactsbook import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import com.airbnb.mvrx.activityViewModel @@ -29,12 +31,14 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentAttachmentsPreviewBinding +import im.vector.app.databinding.FragmentContactsBookBinding import im.vector.app.features.userdirectory.PendingInvitee import im.vector.app.features.userdirectory.UserListAction import im.vector.app.features.userdirectory.UserListSharedAction import im.vector.app.features.userdirectory.UserListSharedActionViewModel import im.vector.app.features.userdirectory.UserListViewModel -import kotlinx.android.synthetic.main.fragment_contacts_book.* + import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.user.model.User import java.util.concurrent.TimeUnit @@ -43,9 +47,12 @@ import javax.inject.Inject class ContactsBookFragment @Inject constructor( val contactsBookViewModelFactory: ContactsBookViewModel.Factory, private val contactsBookController: ContactsBookController -) : VectorBaseFragment(), ContactsBookController.Callback { +) : VectorBaseFragment(), ContactsBookController.Callback { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentContactsBookBinding { + return FragmentContactsBookBinding.inflate(inflater, container, false) + } - override fun getLayoutResId() = R.layout.fragment_contacts_book private val viewModel: UserListViewModel by activityViewModel() // Use activityViewModel to avoid loading several times the data @@ -64,7 +71,7 @@ class ContactsBookFragment @Inject constructor( } private fun setupConsentView() { - phoneBookSearchForMatrixContacts.setOnClickListener { + views.phoneBookSearchForMatrixContacts.setOnClickListener { withState(contactsBookViewModel) { state -> AlertDialog.Builder(requireActivity()) .setTitle(R.string.identity_server_consent_dialog_title) @@ -79,7 +86,7 @@ class ContactsBookFragment @Inject constructor( } private fun setupOnlyBoundContactsView() { - phoneBookOnlyBoundContacts.checkedChanges() + views.phoneBookOnlyBoundContacts.checkedChanges() .subscribe { contactsBookViewModel.handle(ContactsBookAction.OnlyBoundContacts(it)) } @@ -87,7 +94,7 @@ class ContactsBookFragment @Inject constructor( } private fun setupFilterView() { - phoneBookFilter + views.phoneBookFilter .textChanges() .skipInitialValue() .debounce(300, TimeUnit.MILLISECONDS) @@ -98,25 +105,25 @@ class ContactsBookFragment @Inject constructor( } override fun onDestroyView() { - phoneBookRecyclerView.cleanup() + views.phoneBookRecyclerView.cleanup() contactsBookController.callback = null super.onDestroyView() } private fun setupRecyclerView() { contactsBookController.callback = this - phoneBookRecyclerView.configureWith(contactsBookController) + views.phoneBookRecyclerView.configureWith(contactsBookController) } private fun setupCloseView() { - phoneBookClose.debouncedClicks { + views.phoneBookClose.debouncedClicks { sharedActionViewModel.post(UserListSharedAction.GoBack) } } override fun invalidate() = withState(contactsBookViewModel) { state -> - phoneBookSearchForMatrixContacts.isVisible = state.filteredMappedContacts.isNotEmpty() && state.identityServerUrl != null && !state.userConsent - phoneBookOnlyBoundContacts.isVisible = state.isBoundRetrieved + views.phoneBookSearchForMatrixContacts.isVisible = state.filteredMappedContacts.isNotEmpty() && state.identityServerUrl != null && !state.userConsent + views.phoneBookOnlyBoundContacts.isVisible = state.isBoundRetrieved contactsBookController.setData(state) } diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt index 6fafe0b977..7f0ec3ebc2 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomActivity.kt @@ -51,7 +51,7 @@ import im.vector.app.features.userdirectory.UserListSharedAction import im.vector.app.features.userdirectory.UserListSharedActionViewModel import im.vector.app.features.userdirectory.UserListViewModel import im.vector.app.features.userdirectory.UserListViewState -import kotlinx.android.synthetic.main.activity.* + import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import java.net.HttpURLConnection diff --git a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt index 3fee3a3285..83ce9cfe84 100644 --- a/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/createdirect/CreateDirectRoomByQrCodeFragment.kt @@ -16,6 +16,8 @@ package im.vector.app.features.createdirect +import android.view.LayoutInflater +import android.view.ViewGroup import android.widget.Toast import com.airbnb.mvrx.activityViewModel import com.google.zxing.Result @@ -26,19 +28,23 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult +import im.vector.app.databinding.FragmentAttachmentsPreviewBinding +import im.vector.app.databinding.FragmentQrCodeScannerBinding import im.vector.app.features.userdirectory.PendingInvitee -import kotlinx.android.synthetic.main.fragment_qr_code_scanner.* + import me.dm7.barcodescanner.zxing.ZXingScannerView import org.matrix.android.sdk.api.session.permalinks.PermalinkData import org.matrix.android.sdk.api.session.permalinks.PermalinkParser import org.matrix.android.sdk.api.session.user.model.User import javax.inject.Inject -class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler { +class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragment(), ZXingScannerView.ResultHandler { private val viewModel: CreateDirectRoomViewModel by activityViewModel() - override fun getLayoutResId() = R.layout.fragment_qr_code_scanner + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerBinding { + return FragmentQrCodeScannerBinding.inflate(inflater, container, false) + } private val openCameraActivityResultLauncher = registerForPermissionsResult { allGranted -> if (allGranted) { @@ -48,14 +54,14 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen private fun startCamera() { // Start camera on resume - scannerView.startCamera() + views.scannerView.startCamera() } override fun onResume() { super.onResume() view?.hideKeyboard() // Register ourselves as a handler for scan results. - scannerView.setResultHandler(this) + views.scannerView.setResultHandler(this) // Start camera on resume if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), openCameraActivityResultLauncher)) { startCamera() @@ -65,9 +71,9 @@ class CreateDirectRoomByQrCodeFragment @Inject constructor() : VectorBaseFragmen override fun onPause() { super.onPause() // Unregister ourselves as a handler for scan results. - scannerView.setResultHandler(null) + views.scannerView.setResultHandler(null) // Stop camera on pause - scannerView.stopCamera() + views.scannerView.stopCamera() } // Copied from https://github.com/markusfisch/BinaryEye/blob/ diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt index 7d2ec839d4..91a0cf25ce 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromKeyFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.keysbackup.restore import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.widget.doOnTextChanged import androidx.lifecycle.Observer @@ -25,14 +27,18 @@ import im.vector.app.R import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startImportTextFromFileIntent -import kotlinx.android.synthetic.main.fragment_keys_backup_restore_from_key.* +import im.vector.app.databinding.FragmentAttachmentsPreviewBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding + import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject class KeysBackupRestoreFromKeyFragment @Inject constructor() - : VectorBaseFragment() { + : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_key + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreFromKeyBinding { + return FragmentKeysBackupRestoreFromKeyBinding.inflate(inflater, container, false) + } private lateinit var viewModel: KeysBackupRestoreFromKeyViewModel private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel @@ -41,8 +47,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() super.onViewCreated(view, savedInstanceState) viewModel = fragmentViewModelProvider.get(KeysBackupRestoreFromKeyViewModel::class.java) sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) - mKeyTextEdit.setText(viewModel.recoveryCode.value) - mKeyTextEdit.setOnEditorActionListener { _, actionId, _ -> + views.mKeyTextEdit.setText(viewModel.recoveryCode.value) + views.mKeyTextEdit.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { onRestoreFromKey() return@setOnEditorActionListener true @@ -50,14 +56,14 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() return@setOnEditorActionListener false } - mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value + views.mKeyInputLayout.error = viewModel.recoveryCodeErrorText.value viewModel.recoveryCodeErrorText.observe(viewLifecycleOwner, Observer { newValue -> - mKeyInputLayout.error = newValue + views.mKeyInputLayout.error = newValue }) - keys_restore_button.setOnClickListener { onRestoreFromKey() } - keys_backup_import.setOnClickListener { onImport() } - mKeyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) } + views.keysRestoreButton.setOnClickListener { onRestoreFromKey() } + views.keysBackupImport.setOnClickListener { onImport() } + views.mKeyTextEdit.doOnTextChanged { text, _, _, _ -> onRestoreKeyTextEditChange(text) } } private fun onRestoreKeyTextEditChange(s: CharSequence?) { @@ -89,8 +95,8 @@ class KeysBackupRestoreFromKeyFragment @Inject constructor() ?.bufferedReader() ?.use { it.readText() } ?.let { - mKeyTextEdit.setText(it) - mKeyTextEdit.setSelection(it.length) + views.mKeyTextEdit.setText(it) + views.mKeyTextEdit.setSelection(it.length) } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt index 95151b3551..f8b973de12 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreFromPassphraseFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.crypto.keysbackup.restore import android.os.Bundle import android.text.SpannableString import android.text.style.ClickableSpan +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.text.set import androidx.core.widget.doOnTextChanged @@ -26,12 +28,16 @@ import androidx.lifecycle.Observer import im.vector.app.R import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_keys_backup_restore_from_passphrase.* +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromPassphraseBinding + import javax.inject.Inject -class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment() { +class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_from_passphrase + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreFromPassphraseBinding { + return FragmentKeysBackupRestoreFromPassphraseBinding.inflate(inflater, container, false) + } private lateinit var viewModel: KeysBackupRestoreFromPassphraseViewModel private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel @@ -47,18 +53,18 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase sharedViewModel = activityViewModelProvider.get(KeysBackupRestoreSharedViewModel::class.java) viewModel.passphraseErrorText.observe(viewLifecycleOwner, Observer { newValue -> - keys_backup_passphrase_enter_til.error = newValue + views.keysBackupPassphraseEnterTil.error = newValue }) - helperTextWithLink.text = spannableStringForHelperText() + views.helperTextWithLink.text = spannableStringForHelperText() viewModel.showPasswordMode.observe(viewLifecycleOwner, Observer { val shouldBeVisible = it ?: false - keys_backup_passphrase_enter_edittext.showPassword(shouldBeVisible) - keys_backup_view_show_password.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) + views.keysBackupPassphraseEnterEdittext.showPassword(shouldBeVisible) + views.keysBackupViewShowPassword.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) }) - keys_backup_passphrase_enter_edittext.setOnEditorActionListener { _, actionId, _ -> + views.keysBackupPassphraseEnterEdittext.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { onRestoreBackup() return@setOnEditorActionListener true @@ -66,10 +72,10 @@ class KeysBackupRestoreFromPassphraseFragment @Inject constructor() : VectorBase return@setOnEditorActionListener false } - keys_backup_view_show_password.setOnClickListener { toggleVisibilityMode() } - helperTextWithLink.setOnClickListener { onUseRecoveryKey() } - keys_backup_restore_with_passphrase_submit.setOnClickListener { onRestoreBackup() } - keys_backup_passphrase_enter_edittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) } + views.keysBackupViewShowPassword.setOnClickListener { toggleVisibilityMode() } + views.helperTextWithLink.setOnClickListener { onUseRecoveryKey() } + views.keysBackupRestoreWithPassphraseSubmit.setOnClickListener { onRestoreBackup() } + views.keysBackupPassphraseEnterEdittext.doOnTextChanged { text, _, _, _ -> onPassphraseTextEditChange(text) } } private fun spannableStringForHelperText(): SpannableString { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt index 902f376ec4..b93f080ddf 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSuccessFragment.kt @@ -16,17 +16,23 @@ package im.vector.app.features.crypto.keysbackup.restore import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.LiveEvent -import kotlinx.android.synthetic.main.fragment_keys_backup_restore_success.* +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreSuccessBinding + import javax.inject.Inject -class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() { +class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_keys_backup_restore_success + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupRestoreSuccessBinding { + return FragmentKeysBackupRestoreSuccessBinding.inflate(inflater, container, false) + } private lateinit var sharedViewModel: KeysBackupRestoreSharedViewModel @@ -40,15 +46,15 @@ class KeysBackupRestoreSuccessFragment @Inject constructor() : VectorBaseFragmen it.totalNumberOfKeys, it.totalNumberOfKeys) val part2 = resources.getQuantityString(R.plurals.keys_backup_restore_success_description_part2, it.successfullyNumberOfImportedKeys, it.successfullyNumberOfImportedKeys) - mSuccessDetailsText.text = String.format("%s\n%s", part1, part2) + views.mSuccessDetailsText.text = String.format("%s\n%s", part1, part2) } // We don't put emoji in string xml as it will crash on old devices - mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title, "🎉") + views.mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title, "🎉") } else { - mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date) - mSuccessDetailsText.isVisible = false + views.mSuccessText.text = context?.getString(R.string.keys_backup_restore_success_title_already_up_to_date) + views.mSuccessDetailsText.isVisible = false } - keys_backup_setup_done_button.setOnClickListener { onDone() } + views.keysBackupSetupDoneButton.setOnClickListener { onDone() } } private fun onDone() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt index 36ee4d954f..5075280aa9 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsFragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.crypto.keysbackup.settings import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState @@ -24,28 +26,32 @@ import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupSettingsBinding import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity -import kotlinx.android.synthetic.main.fragment_keys_backup_settings.* + import javax.inject.Inject class KeysBackupSettingsFragment @Inject constructor(private val keysBackupSettingsRecyclerViewController: KeysBackupSettingsRecyclerViewController) - : VectorBaseFragment(), + : VectorBaseFragment(), KeysBackupSettingsRecyclerViewController.Listener { - override fun getLayoutResId() = R.layout.fragment_keys_backup_settings + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSettingsBinding { + return FragmentKeysBackupSettingsBinding.inflate(inflater, container, false) + } private val viewModel: KeysBackupSettingsViewModel by activityViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - keysBackupSettingsRecyclerView.configureWith(keysBackupSettingsRecyclerViewController) + views.keysBackupSettingsRecyclerView.configureWith(keysBackupSettingsRecyclerViewController) keysBackupSettingsRecyclerViewController.listener = this } override fun onDestroyView() { keysBackupSettingsRecyclerViewController.listener = null - keysBackupSettingsRecyclerView.cleanup() + views.keysBackupSettingsRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt index c3d5c56189..8db392639d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep1Fragment.kt @@ -17,17 +17,23 @@ package im.vector.app.features.crypto.keysbackup.setup import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.lifecycle.Observer import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.LiveEvent -import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step1.* +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupSetupStep1Binding + import javax.inject.Inject -class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() { +class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_keys_backup_setup_step1 + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentKeysBackupSetupStep1Binding { + return FragmentKeysBackupSetupStep1Binding.inflate(inflater, container, false) + } private lateinit var viewModel: KeysBackupSetupSharedViewModel @@ -39,12 +45,12 @@ class KeysBackupSetupStep1Fragment @Inject constructor() : VectorBaseFragment() viewModel.showManualExport.observe(viewLifecycleOwner, Observer { val showOption = it ?: false // Can't use isVisible because the kotlin compiler will crash with Back-end (JVM) Internal error: wrong code generated - advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE - manualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE + views.advancedOptionText.visibility = if (showOption) View.VISIBLE else View.GONE + views.manualExportButton.visibility = if (showOption) View.VISIBLE else View.GONE }) - keys_backup_setup_step1_button.setOnClickListener { onButtonClick() } - manualExportButton.setOnClickListener { onManualExportClick() } + views.keysBackupSetupStep1Button.setOnClickListener { onButtonClick() } + views.manualExportButton.setOnClickListener { onManualExportClick() } } private fun onButtonClick() { diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt index 93f3b71ced..f81cb09ce0 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep2Fragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.crypto.keysbackup.setup import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.widget.doOnTextChanged import androidx.lifecycle.Observer @@ -26,15 +28,19 @@ import com.nulabinc.zxcvbn.Zxcvbn import im.vector.app.R import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupSetupStep2Binding import im.vector.app.features.settings.VectorLocale -import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step2.* + import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import javax.inject.Inject -class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() { +class KeysBackupSetupStep2Fragment @Inject constructor() : VectorBaseFragment() { - 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() diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt index 94c9b68606..89c73fbecf 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupStep3Fragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.crypto.keysbackup.setup import android.app.Activity import android.net.Uri import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AlertDialog @@ -33,7 +35,9 @@ import im.vector.app.core.utils.LiveEvent import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.selectTxtFileToWrite import im.vector.app.core.utils.startSharePlainTextIntent -import kotlinx.android.synthetic.main.fragment_keys_backup_setup_step3.* +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentKeysBackupSetupStep3Binding + import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -44,9 +48,11 @@ import java.util.Date import java.util.Locale import javax.inject.Inject -class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() { +class KeysBackupSetupStep3Fragment @Inject constructor() : VectorBaseFragment() { - 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 diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt index 2abad9dd38..9e7fde370d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageActivity.kt @@ -35,8 +35,8 @@ import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.platform.SimpleFragmentActivity import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.features.crypto.recover.SetupMode -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject import kotlin.reflect.KClass diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt index 9fb3f637e1..f2d5bf1940 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageKeyFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.crypto.quads import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import com.airbnb.mvrx.activityViewModel import com.jakewharton.rxbinding3.widget.editorActionEvents @@ -27,15 +29,19 @@ import im.vector.app.R import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startImportTextFromFileIntent +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentSsssAccessFromKeyBinding import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_ssss_access_from_key.* + import org.matrix.android.sdk.api.extensions.tryOrNull import java.util.concurrent.TimeUnit import javax.inject.Inject -class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment() { +class SharedSecuredStorageKeyFragment @Inject constructor() : VectorBaseFragment() { - 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() diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt index 97047fbc65..370bd92ccf 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStoragePassphraseFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.quads import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.text.toSpannable import com.airbnb.mvrx.activityViewModel @@ -29,16 +31,20 @@ import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentSsssAccessFromPassphraseBinding import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_ssss_access_from_passphrase.* + import java.util.concurrent.TimeUnit import javax.inject.Inject class SharedSecuredStoragePassphraseFragment @Inject constructor( private val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_ssss_access_from_passphrase + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssAccessFromPassphraseBinding { + return FragmentSsssAccessFromPassphraseBinding.inflate(inflater, container, false) + } val sharedViewModel: SharedSecureStorageViewModel by activityViewModel() @@ -48,7 +54,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor( // If has passphrase val pass = getString(R.string.recovery_passphrase) val key = getString(R.string.recovery_key) - ssss_restore_with_passphrase_warning_text.text = getString( + views.ssssRestoreWithPassphraseWarningText.text = getString( R.string.enter_secret_storage_passphrase_or_key, pass, key @@ -57,7 +63,7 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor( .colorizeMatchingText(pass, colorProvider.getColorFromAttribute(android.R.attr.textColorLink)) .colorizeMatchingText(key, colorProvider.getColorFromAttribute(android.R.attr.textColorLink)) - ssss_passphrase_enter_edittext.editorActionEvents() + views.ssssPassphraseEnterEdittext.editorActionEvents() .throttleFirst(300, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe { @@ -67,40 +73,40 @@ class SharedSecuredStoragePassphraseFragment @Inject constructor( } .disposeOnDestroyView() - ssss_passphrase_enter_edittext.textChanges() + views.ssssPassphraseEnterEdittext.textChanges() .subscribe { - ssss_passphrase_enter_til.error = null - ssss_passphrase_submit.isEnabled = it.isNotBlank() + views.ssssPassphraseEnterTil.error = null + views.ssssPassphraseSubmit.isEnabled = it.isNotBlank() } .disposeOnDestroyView() - ssss_passphrase_reset.clickableView.debouncedClicks { + views.ssssPassphraseReset.clickableView.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.ForgotResetAll) } sharedViewModel.observeViewEvents { when (it) { is SharedSecureStorageViewEvent.InlineError -> { - ssss_passphrase_enter_til.error = it.message + views.ssssPassphraseEnterTil.error = it.message } } } - ssss_passphrase_submit.debouncedClicks { submit() } - ssss_passphrase_use_key.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.UseKey) } - ssss_view_show_password.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.TogglePasswordVisibility) } + views.ssssPassphraseSubmit.debouncedClicks { submit() } + views.ssssPassphraseUseKey.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.UseKey) } + views.ssssViewShowPassword.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.TogglePasswordVisibility) } } fun submit() { - val text = ssss_passphrase_enter_edittext.text.toString() + val text = views.ssssPassphraseEnterEdittext.text.toString() if (text.isBlank()) return // Should not reach this point as button disabled - ssss_passphrase_submit.isEnabled = false + views.ssssPassphraseSubmit.isEnabled = false sharedViewModel.handle(SharedSecureStorageAction.SubmitPassphrase(text)) } override fun invalidate() = withState(sharedViewModel) { state -> val shouldBeVisible = state.passphraseVisible - ssss_passphrase_enter_edittext.showPassword(shouldBeVisible) - ssss_view_show_password.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) + views.ssssPassphraseEnterEdittext.showPassword(shouldBeVisible) + views.ssssViewShowPassword.setImageResource(if (shouldBeVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt index d7db779230..47a73bb325 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecuredStorageResetAllFragment.kt @@ -17,41 +17,48 @@ package im.vector.app.features.crypto.quads import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentSsssResetAllBinding import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet -import kotlinx.android.synthetic.main.fragment_ssss_reset_all.* + import javax.inject.Inject -class SharedSecuredStorageResetAllFragment @Inject constructor() : VectorBaseFragment() { +class SharedSecuredStorageResetAllFragment @Inject constructor() + : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_ssss_reset_all + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSsssResetAllBinding { + return FragmentSsssResetAllBinding.inflate(inflater, container, false) + } val sharedViewModel: SharedSecureStorageViewModel by activityViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - ssss_reset_button_reset.debouncedClicks { + views.ssssResetButtonReset.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.DoResetAll) } - ssss_reset_button_cancel.debouncedClicks { + views.ssssResetButtonCancel.debouncedClicks { sharedViewModel.handle(SharedSecureStorageAction.Back) } - ssss_reset_other_devices.debouncedClicks { + views.ssssResetOtherDevices.debouncedClicks { withState(sharedViewModel) { DeviceListBottomSheet.newInstance(it.userId, false).show(childFragmentManager, "DEV_LIST") } } sharedViewModel.subscribe(this) { state -> - ssss_reset_other_devices.setTextOrHide( + views.ssssResetOtherDevices.setTextOrHide( state.activeDeviceCount .takeIf { it > 0 } ?.let { resources.getQuantityString(R.plurals.secure_backup_reset_devices_you_can_verify, it, it) } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt index ccf2d67701..6d951c3433 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapAccountPasswordFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.recover import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.text.toSpannable import com.airbnb.mvrx.parentFragmentViewModel @@ -30,18 +32,22 @@ import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText +import im.vector.app.databinding.FragmentBootstrapEnterAccountPasswordBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_account_password.* -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.bootstrapDescriptionText -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.ssss_view_show_password + + + import java.util.concurrent.TimeUnit import javax.inject.Inject class BootstrapAccountPasswordFragment @Inject constructor( private val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - 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() diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt index e6260b6e7e..97fe93ad04 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapBottomSheet.kt @@ -36,12 +36,14 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_bootstrap.* +import im.vector.app.databinding.BottomSheetBootstrapBinding +import im.vector.app.databinding.BottomSheetGenericListBinding +import kotlinx.parcelize.Parcelize + import javax.inject.Inject import kotlin.reflect.KClass -class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { +class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize data class Args( @@ -59,7 +61,9 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_bootstrap + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetBootstrapBinding { + return BottomSheetBootstrapBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -120,60 +124,60 @@ class BootstrapBottomSheet : VectorBaseBottomSheetDialogFragment() { override fun invalidate() = withState(viewModel) { state -> when (state.step) { is BootstrapStep.CheckingMigration -> { - bootstrapIcon.isVisible = false - bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title) + views.bootstrapIcon.isVisible = false + views.bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title) showFragment(BootstrapWaitingFragment::class, Bundle()) } is BootstrapStep.FirstForm -> { - bootstrapIcon.isVisible = false - bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title) + views.bootstrapIcon.isVisible = false + views.bootstrapTitleText.text = getString(R.string.bottom_sheet_setup_secure_backup_title) showFragment(BootstrapSetupRecoveryKeyFragment::class, Bundle()) } is BootstrapStep.SetupPassphrase -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp)) - bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp)) + views.bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title) showFragment(BootstrapEnterPassphraseFragment::class, Bundle()) } is BootstrapStep.ConfirmPassphrase -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp)) - bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_phrase_24dp)) + views.bootstrapTitleText.text = getString(R.string.set_a_security_phrase_title) showFragment(BootstrapConfirmPassphraseFragment::class, Bundle()) } is BootstrapStep.AccountPassword -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user)) - bootstrapTitleText.text = getString(R.string.account_password) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_user)) + views.bootstrapTitleText.text = getString(R.string.account_password) showFragment(BootstrapAccountPasswordFragment::class, Bundle()) } is BootstrapStep.Initializing -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) - bootstrapTitleText.text = getString(R.string.bootstrap_loading_title) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) + views.bootstrapTitleText.text = getString(R.string.bootstrap_loading_title) showFragment(BootstrapWaitingFragment::class, Bundle()) } is BootstrapStep.SaveRecoveryKey -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) - bootstrapTitleText.text = getString(R.string.bottom_sheet_save_your_recovery_key_title) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) + views.bootstrapTitleText.text = getString(R.string.bottom_sheet_save_your_recovery_key_title) showFragment(BootstrapSaveRecoveryKeyFragment::class, Bundle()) } is BootstrapStep.DoneSuccess -> { - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) - bootstrapTitleText.text = getString(R.string.bootstrap_finish_title) + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable(requireContext(), R.drawable.ic_security_key_24dp)) + views.bootstrapTitleText.text = getString(R.string.bootstrap_finish_title) showFragment(BootstrapConclusionFragment::class, Bundle()) } is BootstrapStep.GetBackupSecretForMigration -> { val isKey = state.step.useKey() val drawableRes = if (isKey) R.drawable.ic_security_key_24dp else R.drawable.ic_security_phrase_24dp - bootstrapIcon.isVisible = true - bootstrapIcon.setImageDrawable(ContextCompat.getDrawable( + views.bootstrapIcon.isVisible = true + views.bootstrapIcon.setImageDrawable(ContextCompat.getDrawable( requireContext(), drawableRes) ) - bootstrapTitleText.text = getString(R.string.upgrade_security) + views.bootstrapTitleText.text = getString(R.string.upgrade_security) showFragment(BootstrapMigrateBackupFragment::class, Bundle()) } }.exhaustive diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt index a50d9e6dff..fcf20dcdcd 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConclusionFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.recover import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.text.toSpannable import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -25,27 +27,31 @@ import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText -import kotlinx.android.synthetic.main.fragment_bootstrap_conclusion.* +import im.vector.app.databinding.FragmentBootstrapConclusionBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding + import javax.inject.Inject class BootstrapConclusionFragment @Inject constructor( private val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_bootstrap_conclusion + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapConclusionBinding { + return FragmentBootstrapConclusionBinding.inflate(inflater, container, false) + } val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bootstrapConclusionContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Completed) } + views.bootstrapConclusionContinue.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Completed) } } override fun invalidate() = withState(sharedViewModel) { state -> if (state.step !is BootstrapStep.DoneSuccess) return@withState - bootstrapConclusionText.text = getString( + views.bootstrapConclusionText.text = getString( R.string.bootstrap_cross_signing_success, getString(R.string.recovery_passphrase), getString(R.string.message_key) diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt index 46e9315477..ab3a87905f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapConfirmPassphraseFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.recover import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.view.isGone import com.airbnb.mvrx.parentFragmentViewModel @@ -28,14 +30,19 @@ import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.* + import java.util.concurrent.TimeUnit import javax.inject.Inject -class BootstrapConfirmPassphraseFragment @Inject constructor() : VectorBaseFragment() { +class BootstrapConfirmPassphraseFragment @Inject constructor() + : VectorBaseFragment() { - 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() diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt index 53c3ee4356..2098bbb28f 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapEnterPassphraseFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.recover import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -26,29 +28,34 @@ import com.jakewharton.rxbinding3.widget.textChanges import im.vector.app.R import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentBootstrapEnterPassphraseBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import im.vector.app.features.settings.VectorLocale import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.* + import java.util.concurrent.TimeUnit import javax.inject.Inject -class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragment() { +class BootstrapEnterPassphraseFragment @Inject constructor() + : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_bootstrap_enter_passphrase + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapEnterPassphraseBinding { + return FragmentBootstrapEnterPassphraseBinding.inflate(inflater, container, false) + } val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bootstrapDescriptionText.text = getString(R.string.set_a_security_phrase_notice) - ssss_passphrase_enter_edittext.hint = getString(R.string.set_a_security_phrase_hint) + views.bootstrapDescriptionText.text = getString(R.string.set_a_security_phrase_notice) + views.ssssPassphraseEnterEdittext.hint = getString(R.string.set_a_security_phrase_hint) withState(sharedViewModel) { // set initial value (useful when coming back) - ssss_passphrase_enter_edittext.setText(it.passphrase ?: "") + views.ssssPassphraseEnterEdittext.setText(it.passphrase ?: "") } - ssss_passphrase_enter_edittext.editorActionEvents() + views.ssssPassphraseEnterEdittext.editorActionEvents() .throttleFirst(300, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe { @@ -58,7 +65,7 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen } .disposeOnDestroyView() - ssss_passphrase_enter_edittext.textChanges() + views.ssssPassphraseEnterEdittext.textChanges() .subscribe { // ssss_passphrase_enter_til.error = null sharedViewModel.handle(BootstrapActions.UpdateCandidatePassphrase(it?.toString() ?: "")) @@ -74,8 +81,8 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen // } } - ssss_view_show_password.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) } - bootstrapSubmit.debouncedClicks { submit() } + views.ssssViewShowPassword.debouncedClicks { sharedViewModel.handle(BootstrapActions.TogglePasswordVisibility) } + views.bootstrapSubmit.debouncedClicks { submit() } } private fun submit() = withState(sharedViewModel) { state -> @@ -83,11 +90,11 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen return@withState } val score = state.passphraseStrength.invoke()?.score - val passphrase = ssss_passphrase_enter_edittext.text?.toString() + val passphrase = views.ssssPassphraseEnterEdittext.text?.toString() if (passphrase.isNullOrBlank()) { - ssss_passphrase_enter_til.error = getString(R.string.passphrase_empty_error_message) + views.ssssPassphraseEnterTil.error = getString(R.string.passphrase_empty_error_message) } else if (score != 4) { - ssss_passphrase_enter_til.error = getString(R.string.passphrase_passphrase_too_weak) + views.ssssPassphraseEnterTil.error = getString(R.string.passphrase_passphrase_too_weak) } else { sharedViewModel.handle(BootstrapActions.GoToConfirmPassphrase(passphrase)) } @@ -96,21 +103,21 @@ class BootstrapEnterPassphraseFragment @Inject constructor() : VectorBaseFragmen override fun invalidate() = withState(sharedViewModel) { state -> if (state.step is BootstrapStep.SetupPassphrase) { val isPasswordVisible = state.step.isPasswordVisible - ssss_passphrase_enter_edittext.showPassword(isPasswordVisible, updateCursor = false) - ssss_view_show_password.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) + views.ssssPassphraseEnterEdittext.showPassword(isPasswordVisible, updateCursor = false) + views.ssssViewShowPassword.setImageResource(if (isPasswordVisible) R.drawable.ic_eye_closed else R.drawable.ic_eye) state.passphraseStrength.invoke()?.let { strength -> val score = strength.score - ssss_passphrase_security_progress.strength = score + views.ssssPassphraseSecurityProgress.strength = score if (score in 1..3) { val hint = strength.feedback?.getWarning(VectorLocale.applicationLocale)?.takeIf { it.isNotBlank() } ?: strength.feedback?.getSuggestions(VectorLocale.applicationLocale)?.firstOrNull() - if (hint != null && hint != ssss_passphrase_enter_til.error.toString()) { - ssss_passphrase_enter_til.error = hint + if (hint != null && hint != views.ssssPassphraseEnterTil.error.toString()) { + views.ssssPassphraseEnterTil.error = hint } } else { - ssss_passphrase_enter_til.error = null + views.ssssPassphraseEnterTil.error = null } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt index 0e3ba4c526..c45702d95a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt @@ -21,7 +21,9 @@ import android.os.Bundle import android.text.InputType.TYPE_CLASS_TEXT import android.text.InputType.TYPE_TEXT_FLAG_MULTI_LINE import android.text.InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.core.text.toSpannable import androidx.core.view.isVisible @@ -37,9 +39,11 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText import im.vector.app.core.utils.startImportTextFromFileIntent +import im.vector.app.databinding.FragmentBootstrapMigrateBackupBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.fragment_bootstrap_enter_passphrase.bootstrapDescriptionText -import kotlinx.android.synthetic.main.fragment_bootstrap_migrate_backup.* + + import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.internal.crypto.keysbackup.util.isValidRecoveryKey import java.util.concurrent.TimeUnit @@ -47,9 +51,11 @@ import javax.inject.Inject class BootstrapMigrateBackupFragment @Inject constructor( private val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - 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() diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt index e426394d77..7962233418 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSaveRecoveryKeyFragment.kt @@ -20,7 +20,9 @@ import android.app.Activity import android.content.ActivityNotFoundException import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -30,7 +32,9 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.startSharePlainTextIntent import im.vector.app.core.utils.toast -import kotlinx.android.synthetic.main.fragment_bootstrap_save_key.* +import im.vector.app.databinding.FragmentBootstrapSaveKeyBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding + import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch @@ -38,18 +42,20 @@ import javax.inject.Inject class BootstrapSaveRecoveryKeyFragment @Inject constructor( private val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_bootstrap_save_key + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapSaveKeyBinding { + return FragmentBootstrapSaveKeyBinding.inflate(inflater, container, false) + } val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() } - recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() } - recoveryContinue.clickableView.debouncedClicks { + views.recoverySave.clickableView.debouncedClicks { downloadRecoveryKey() } + views.recoveryCopy.clickableView.debouncedClicks { shareRecoveryKey() } + views.recoveryContinue.clickableView.debouncedClicks { // We do not display the final Fragment anymore // TODO Do some cleanup // sharedViewModel.handle(BootstrapActions.GoToCompleted) @@ -112,7 +118,7 @@ class BootstrapSaveRecoveryKeyFragment @Inject constructor( val step = state.step if (step !is BootstrapStep.SaveRecoveryKey) return@withState - recoveryContinue.isVisible = step.isSaved - bootstrapRecoveryKeyText.text = state.recoveryKeyCreationInfo?.recoveryKey?.formatRecoveryKey() + views.recoveryContinue.isVisible = step.isSaved + views.bootstrapRecoveryKeyText.text = state.recoveryKeyCreationInfo?.recoveryKey?.formatRecoveryKey() } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt index ed68e3daac..23db24298e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSetupRecoveryKeyFragment.kt @@ -17,18 +17,25 @@ package im.vector.app.features.crypto.recover import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_bootstrap_setup_recovery.* +import im.vector.app.databinding.FragmentBootstrapSetupRecoveryBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding + import javax.inject.Inject -class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragment() { +class BootstrapSetupRecoveryKeyFragment @Inject constructor() + : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_bootstrap_setup_recovery + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapSetupRecoveryBinding { + return FragmentBootstrapSetupRecoveryBinding.inflate(inflater, container, false) + } val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() @@ -36,15 +43,15 @@ class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragme super.onViewCreated(view, savedInstanceState) // Actions when a key backup exist - bootstrapSetupSecureSubmit.clickableView.debouncedClicks { + views.bootstrapSetupSecureSubmit.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.StartKeyBackupMigration) } // Actions when there is no key backup - bootstrapSetupSecureUseSecurityKey.clickableView.debouncedClicks { + views.bootstrapSetupSecureUseSecurityKey.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Start(userWantsToEnterPassphrase = false)) } - bootstrapSetupSecureUseSecurityPassphrase.clickableView.debouncedClicks { + views.bootstrapSetupSecureUseSecurityPassphrase.clickableView.debouncedClicks { sharedViewModel.handle(BootstrapActions.Start(userWantsToEnterPassphrase = true)) } } @@ -53,23 +60,23 @@ class BootstrapSetupRecoveryKeyFragment @Inject constructor() : VectorBaseFragme if (state.step is BootstrapStep.FirstForm) { if (state.step.keyBackUpExist) { // Display the set up action - bootstrapSetupSecureSubmit.isVisible = true - bootstrapSetupSecureUseSecurityKey.isVisible = false - bootstrapSetupSecureUseSecurityPassphrase.isVisible = false - bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = false + views.bootstrapSetupSecureSubmit.isVisible = true + views.bootstrapSetupSecureUseSecurityKey.isVisible = false + views.bootstrapSetupSecureUseSecurityPassphrase.isVisible = false + views.bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = false } else { if (state.step.reset) { - bootstrapSetupSecureText.text = getString(R.string.reset_secure_backup_title) - bootstrapSetupWarningTextView.isVisible = true + views.bootstrapSetupSecureText.text = getString(R.string.reset_secure_backup_title) + views.bootstrapSetupWarningTextView.isVisible = true } else { - bootstrapSetupSecureText.text = getString(R.string.bottom_sheet_setup_secure_backup_subtitle) - bootstrapSetupWarningTextView.isVisible = false + views.bootstrapSetupSecureText.text = getString(R.string.bottom_sheet_setup_secure_backup_subtitle) + views.bootstrapSetupWarningTextView.isVisible = false } // Choose between create a passphrase or use a recovery key - bootstrapSetupSecureSubmit.isVisible = false - bootstrapSetupSecureUseSecurityKey.isVisible = true - bootstrapSetupSecureUseSecurityPassphrase.isVisible = true - bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = true + views.bootstrapSetupSecureSubmit.isVisible = false + views.bootstrapSetupSecureUseSecurityKey.isVisible = true + views.bootstrapSetupSecureUseSecurityPassphrase.isVisible = true + views.bootstrapSetupSecureUseSecurityPassphraseSeparator.isVisible = true } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt index 0004420494..0e3eaa85d2 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapWaitingFragment.kt @@ -16,26 +16,33 @@ package im.vector.app.features.crypto.recover +import android.view.LayoutInflater +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_bootstrap_waiting.* +import im.vector.app.databinding.FragmentBootstrapWaitingBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding + import javax.inject.Inject -class BootstrapWaitingFragment @Inject constructor() : VectorBaseFragment() { +class BootstrapWaitingFragment @Inject constructor() + : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_bootstrap_waiting + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBootstrapWaitingBinding { + return FragmentBootstrapWaitingBinding.inflate(inflater, container, false) + } val sharedViewModel: BootstrapSharedViewModel by parentFragmentViewModel() override fun invalidate() = withState(sharedViewModel) { state -> when (state.step) { is BootstrapStep.Initializing -> { - bootstrapLoadingStatusText.isVisible = true - bootstrapDescriptionText.isVisible = true - bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message + views.bootstrapLoadingStatusText.isVisible = true + views.bootstrapDescriptionText.isVisible = true + views.bootstrapLoadingStatusText.text = state.initializationWaitingViewData?.message } // is BootstrapStep.CheckingMigration -> { // bootstrapLoadingStatusText.isVisible = false @@ -43,8 +50,8 @@ class BootstrapWaitingFragment @Inject constructor() : VectorBaseFragment() { // } else -> { // just show the spinner - bootstrapLoadingStatusText.isVisible = false - bootstrapDescriptionText.isVisible = false + views.bootstrapLoadingStatusText.isVisible = false + views.bootstrapDescriptionText.isVisible = false } } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/QuadSLoadingFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/QuadSLoadingFragment.kt index a0ab1c86a7..6b6e94f043 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/QuadSLoadingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/QuadSLoadingFragment.kt @@ -16,10 +16,16 @@ package im.vector.app.features.crypto.verification +import android.view.LayoutInflater +import android.view.ViewGroup import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding +import im.vector.app.databinding.FragmentProgressBinding import javax.inject.Inject -class QuadSLoadingFragment @Inject constructor() : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_progress +class QuadSLoadingFragment @Inject constructor() : VectorBaseFragment() { + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentProgressBinding { + return FragmentProgressBinding.inflate(inflater, container, false) + } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index 6a9e89f4f5..53d55ed2ee 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -20,7 +20,9 @@ import android.app.Dialog import android.os.Bundle import android.os.Parcelable import android.view.KeyEvent +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import androidx.fragment.app.Fragment @@ -34,6 +36,8 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetVerificationBinding import im.vector.app.features.crypto.quads.SharedSecureStorageActivity import im.vector.app.features.crypto.verification.cancel.VerificationCancelFragment import im.vector.app.features.crypto.verification.cancel.VerificationNotMeFragment @@ -45,8 +49,8 @@ import im.vector.app.features.crypto.verification.qrconfirmation.VerificationQrS import im.vector.app.features.crypto.verification.request.VerificationRequestFragment import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.settings.VectorSettingsActivity -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_verification.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME @@ -58,7 +62,7 @@ import timber.log.Timber import javax.inject.Inject import kotlin.reflect.KClass -class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { +class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { @Parcelize data class VerificationArgs( @@ -84,7 +88,9 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_verification + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationBinding { + return BottomSheetVerificationBinding.inflate(inflater, container, false) + } init { isCancelable = false @@ -115,7 +121,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { } VerificationBottomSheetViewEvents.GoToSettings -> { dismiss() - (activity as? VectorBaseActivity)?.navigator?.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY) + (activity as? VectorBaseActivity<*>)?.navigator?.openSettings(requireContext(), VectorSettingsActivity.EXTRA_DIRECT_ACCESS_SECURITY_PRIVACY) } }.exhaustive } @@ -152,27 +158,27 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { override fun invalidate() = withState(viewModel) { state -> state.otherUserMxItem?.let { matrixItem -> if (state.isMe) { - avatarRenderer.render(matrixItem, otherUserAvatarImageView) + avatarRenderer.render(matrixItem, views.otherUserAvatarImageView) if (state.sasTransactionState == VerificationTxState.Verified || state.qrTransactionState == VerificationTxState.Verified || state.verifiedFromPrivateKeys) { - otherUserShield.setImageResource(R.drawable.ic_shield_trusted) + views.otherUserShield.setImageResource(R.drawable.ic_shield_trusted) } else { - otherUserShield.setImageResource(R.drawable.ic_shield_warning) + views.otherUserShield.setImageResource(R.drawable.ic_shield_warning) } - otherUserNameText.text = getString( + views.otherUserNameText.text = getString( if (state.selfVerificationMode) R.string.crosssigning_verify_this_session else R.string.crosssigning_verify_session ) - otherUserShield.isVisible = true + views.otherUserShield.isVisible = true } else { - avatarRenderer.render(matrixItem, otherUserAvatarImageView) + avatarRenderer.render(matrixItem, views.otherUserAvatarImageView) if (state.sasTransactionState == VerificationTxState.Verified || state.qrTransactionState == VerificationTxState.Verified) { - otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName()) - otherUserShield.isVisible = true + views.otherUserNameText.text = getString(R.string.verification_verified_user, matrixItem.getBestName()) + views.otherUserShield.isVisible = true } else { - otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName()) - otherUserShield.isVisible = false + views.otherUserNameText.text = getString(R.string.verification_verify_user, matrixItem.getBestName()) + views.otherUserShield.isVisible = false } } } @@ -189,13 +195,13 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { } if (state.userThinkItsNotHim) { - otherUserNameText.text = getString(R.string.dialog_title_warning) + views.otherUserNameText.text = getString(R.string.dialog_title_warning) showFragment(VerificationNotMeFragment::class, Bundle()) return@withState } if (state.userWantsToCancel) { - otherUserNameText.text = getString(R.string.are_you_sure) + views.otherUserNameText.text = getString(R.string.are_you_sure) showFragment(VerificationCancelFragment::class, Bundle()) return@withState } @@ -287,7 +293,7 @@ class VerificationBottomSheet : VectorBaseBottomSheetDialogFragment() { // Transaction has not yet started if (state.pendingRequest.invoke()?.cancelConclusion != null) { // The request has been declined, we should dismiss - otherUserNameText.text = getString(R.string.verification_cancelled) + views.otherUserNameText.text = getString(R.string.verification_cancelled) showFragment(VerificationConclusionFragment::class, Bundle().apply { putParcelable(MvRx.KEY_ARG, VerificationConclusionFragment.Args( false, diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt index 8e31cd2fab..75f6afa1aa 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationCancelFragment.kt @@ -17,24 +17,31 @@ package im.vector.app.features.crypto.verification.cancel import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import javax.inject.Inject class VerificationCancelFragment @Inject constructor( val controller: VerificationCancelController -) : VectorBaseFragment(), VerificationCancelController.Listener { +) : VectorBaseFragment(), + VerificationCancelController.Listener { private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -42,13 +49,13 @@ class VerificationCancelFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt index 5059c2a2c9..7e5892ce67 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/cancel/VerificationNotMeFragment.kt @@ -17,24 +17,31 @@ package im.vector.app.features.crypto.verification.cancel import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding +import im.vector.app.databinding.FragmentKeysBackupRestoreFromKeyBinding import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import javax.inject.Inject class VerificationNotMeFragment @Inject constructor( val controller: VerificationNotMeController -) : VectorBaseFragment(), VerificationNotMeController.Listener { +) : VectorBaseFragment(), + VerificationNotMeController.Listener { private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -42,13 +49,13 @@ class VerificationNotMeFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt index 72cd063bbd..185fd85196 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/choose/VerificationChooseMethodFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.verification.choose import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -29,23 +31,27 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel import im.vector.app.features.qrcode.QrCodeScannerActivity -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import timber.log.Timber import javax.inject.Inject class VerificationChooseMethodFragment @Inject constructor( val verificationChooseMethodViewModelFactory: VerificationChooseMethodViewModel.Factory, val controller: VerificationChooseMethodController -) : VectorBaseFragment(), VerificationChooseMethodController.Listener { +) : VectorBaseFragment(), + VerificationChooseMethodController.Listener { private val viewModel by fragmentViewModel(VerificationChooseMethodViewModel::class) private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -54,13 +60,13 @@ class VerificationChooseMethodFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionFragment.kt index 885cc8f853..45e1617be1 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.crypto.verification.conclusion import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -25,15 +27,17 @@ import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject class VerificationConclusionFragment @Inject constructor( val controller: VerificationConclusionController -) : VectorBaseFragment(), VerificationConclusionController.Listener { +) : VectorBaseFragment(), + VerificationConclusionController.Listener { @Parcelize data class Args( @@ -46,7 +50,9 @@ class VerificationConclusionFragment @Inject constructor( private val viewModel by fragmentViewModel(VerificationConclusionViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -55,13 +61,13 @@ class VerificationConclusionFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt index 20d0d7de75..27d5a8811a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/emoji/VerificationEmojiCodeFragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.crypto.verification.emoji import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState @@ -24,21 +26,25 @@ import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import javax.inject.Inject class VerificationEmojiCodeFragment @Inject constructor( val viewModelFactory: VerificationEmojiCodeViewModel.Factory, val controller: VerificationEmojiCodeController -) : VectorBaseFragment(), VerificationEmojiCodeController.Listener { +) : VectorBaseFragment(), + VerificationEmojiCodeController.Listener { private val viewModel by fragmentViewModel(VerificationEmojiCodeViewModel::class) private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -47,13 +53,13 @@ class VerificationEmojiCodeFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingFragment.kt index c2d7536134..0fdcb69d31 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingFragment.kt @@ -18,19 +18,22 @@ package im.vector.app.features.crypto.verification.qrconfirmation import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.MvRx import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding +import kotlinx.parcelize.Parcelize + import javax.inject.Inject class VerificationQRWaitingFragment @Inject constructor( val controller: VerificationQRWaitingController -) : VectorBaseFragment() { +) : VectorBaseFragment() { @Parcelize data class Args( @@ -38,7 +41,9 @@ class VerificationQRWaitingFragment @Inject constructor( val otherUserName: String ) : Parcelable - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -49,11 +54,11 @@ class VerificationQRWaitingFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) } } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt index 7e9b19e491..37ca016185 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherFragment.kt @@ -16,25 +16,31 @@ package im.vector.app.features.crypto.verification.qrconfirmation import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import javax.inject.Inject class VerificationQrScannedByOtherFragment @Inject constructor( val controller: VerificationQrScannedByOtherController -) : VectorBaseFragment(), VerificationQrScannedByOtherController.Listener { +) : VectorBaseFragment(), + VerificationQrScannedByOtherController.Listener { private val sharedViewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -46,13 +52,13 @@ class VerificationQrScannedByOtherFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt index fc7dcaf15f..40bcbc6c08 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/request/VerificationRequestFragment.kt @@ -16,25 +16,31 @@ package im.vector.app.features.crypto.verification.request import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding import im.vector.app.features.crypto.verification.VerificationAction import im.vector.app.features.crypto.verification.VerificationBottomSheetViewModel -import kotlinx.android.synthetic.main.bottom_sheet_verification_child_fragment.* + import javax.inject.Inject class VerificationRequestFragment @Inject constructor( val controller: VerificationRequestController -) : VectorBaseFragment(), VerificationRequestController.Listener { +) : VectorBaseFragment(), + VerificationRequestController.Listener { private val viewModel by parentFragmentViewModel(VerificationBottomSheetViewModel::class) - override fun getLayoutResId() = R.layout.bottom_sheet_verification_child_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetVerificationChildFragmentBinding { + return BottomSheetVerificationChildFragmentBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -42,13 +48,13 @@ class VerificationRequestFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetVerificationRecyclerView.cleanup() + views.bottomSheetVerificationRecyclerView.cleanup() controller.listener = null super.onDestroyView() } private fun setupRecyclerView() { - bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetVerificationRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt index 08bf2f12f0..917da224b1 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsFragment.kt @@ -17,8 +17,11 @@ package im.vector.app.features.discovery import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -30,9 +33,11 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.ensureProtocol +import im.vector.app.databinding.BottomSheetVerificationChildFragmentBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.discovery.change.SetIdentityServerFragment import im.vector.app.features.settings.VectorSettingsActivity -import kotlinx.android.synthetic.main.fragment_generic_recycler.* + import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.terms.TermsService @@ -41,9 +46,12 @@ import javax.inject.Inject class DiscoverySettingsFragment @Inject constructor( private val controller: DiscoverySettingsController, val viewModelFactory: DiscoverySettingsViewModel.Factory -) : VectorBaseFragment(), DiscoverySettingsController.Listener { +) : VectorBaseFragment(), + DiscoverySettingsController.Listener { - override fun getLayoutResId() = R.layout.fragment_generic_recycler + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } private val viewModel by fragmentViewModel(DiscoverySettingsViewModel::class) @@ -55,7 +63,7 @@ class DiscoverySettingsFragment @Inject constructor( sharedViewModel = activityViewModelProvider.get(DiscoverySharedViewModel::class.java) controller.listener = this - genericRecyclerView.configureWith(controller) + views.genericRecyclerView.configureWith(controller) sharedViewModel.navigateEvent.observeEvent(this) { when (it) { @@ -74,7 +82,7 @@ class DiscoverySettingsFragment @Inject constructor( } override fun onDestroyView() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() controller.listener = null super.onDestroyView() } @@ -85,7 +93,7 @@ class DiscoverySettingsFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_discovery_category) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_discovery_category) // If some 3pids are pending, we can try to check if they have been verified here viewModel.handle(DiscoverySettingsAction.Refresh) diff --git a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt index 8fb4fc4156..e26e85b23d 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/change/SetIdentityServerFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.discovery.change import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.appcompat.app.AlertDialog import androidx.core.text.toSpannable @@ -33,17 +35,21 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.colorizeMatchingText +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentSetIdentityServerBinding import im.vector.app.features.discovery.DiscoverySharedViewModel -import kotlinx.android.synthetic.main.fragment_set_identity_server.* + import org.matrix.android.sdk.api.session.terms.TermsService import javax.inject.Inject class SetIdentityServerFragment @Inject constructor( val viewModelFactory: SetIdentityServerViewModel.Factory, val colorProvider: ColorProvider -) : VectorBaseFragment() { +) : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_set_identity_server + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSetIdentityServerBinding { + return FragmentSetIdentityServerBinding.inflate(inflater, container, false) + } private val viewModel by fragmentViewModel(SetIdentityServerViewModel::class) @@ -147,7 +153,7 @@ class SetIdentityServerFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.identity_server) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.identity_server) } private val termsActivityResultLauncher = registerStartForActivityResult { diff --git a/vector/src/main/java/im/vector/app/features/grouplist/GroupListFragment.kt b/vector/src/main/java/im/vector/app/features/grouplist/GroupListFragment.kt index d4ba4f3150..0b800c0524 100644 --- a/vector/src/main/java/im/vector/app/features/grouplist/GroupListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/grouplist/GroupListFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.grouplist import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.Incomplete import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel @@ -29,28 +31,33 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentGroupListBinding import im.vector.app.features.home.HomeActivitySharedAction import im.vector.app.features.home.HomeSharedActionViewModel -import kotlinx.android.synthetic.main.fragment_group_list.* + import org.matrix.android.sdk.api.session.group.model.GroupSummary import javax.inject.Inject class GroupListFragment @Inject constructor( val groupListViewModelFactory: GroupListViewModel.Factory, private val groupController: GroupSummaryController -) : VectorBaseFragment(), GroupSummaryController.Callback { +) : VectorBaseFragment(), + GroupSummaryController.Callback { private lateinit var sharedActionViewModel: HomeSharedActionViewModel private val viewModel: GroupListViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_group_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGroupListBinding { + return FragmentGroupListBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(HomeSharedActionViewModel::class.java) groupController.callback = this - stateView.contentView = groupListView - groupListView.configureWith(groupController) + views.stateView.contentView = views.groupListView + views.groupListView.configureWith(groupController) viewModel.observeViewEvents { when (it) { is GroupListViewEvents.OpenGroupSummary -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup) @@ -60,14 +67,14 @@ class GroupListFragment @Inject constructor( override fun onDestroyView() { groupController.callback = null - groupListView.cleanup() + views.groupListView.cleanup() super.onDestroyView() } override fun invalidate() = withState(viewModel) { state -> when (state.asyncGroups) { - is Incomplete -> stateView.state = StateView.State.Loading - is Success -> stateView.state = StateView.State.Content + is Incomplete -> views.stateView.state = StateView.State.Loading + is Success -> views.stateView.state = StateView.State.Content } groupController.update(state) } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index d4aff21c40..8b4c462a5a 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -21,8 +21,10 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.MenuItem import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat import androidx.core.view.GravityCompat @@ -40,6 +42,7 @@ import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.pushers.PushersManager import im.vector.app.core.utils.toast +import im.vector.app.databinding.ActivityHomeBinding import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.notifications.NotificationDrawerManager @@ -56,9 +59,9 @@ import im.vector.app.features.workers.signout.ServerBackupStatusViewModel import im.vector.app.features.workers.signout.ServerBackupStatusViewState import im.vector.app.push.fcm.FcmHelper import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity_home.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import kotlinx.parcelize.Parcelize + + import org.matrix.android.sdk.api.session.InitialSyncProgressService import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.util.MatrixItem @@ -71,7 +74,11 @@ data class HomeActivityArgs( val accountCreation: Boolean ) : Parcelable -class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDetectorSharedViewModel.Factory, ServerBackupStatusViewModel.Factory, +class HomeActivity : + VectorBaseActivity(), + ToolbarConfigurable, + UnknownDeviceDetectorSharedViewModel.Factory, + ServerBackupStatusViewModel.Factory, NavigationInterceptor { private lateinit var sharedActionViewModel: HomeSharedActionViewModel @@ -98,7 +105,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet } } - override fun getLayoutRes() = R.layout.activity_home + override fun getBinding() = ActivityHomeBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -116,7 +123,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet super.onCreate(savedInstanceState) FcmHelper.ensureFcmTokenIsRetrieved(this, pushManager, vectorPreferences.areNotificationEnabledForDevice()) sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java) - drawerLayout.addDrawerListener(drawerListener) + views.drawerLayout.addDrawerListener(drawerListener) if (isFirstCreation()) { replaceFragment(R.id.homeDetailFragmentContainer, LoadingFragment::class.java) replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java) @@ -126,10 +133,10 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet .observe() .subscribe { sharedAction -> when (sharedAction) { - is HomeActivitySharedAction.OpenDrawer -> drawerLayout.openDrawer(GravityCompat.START) - is HomeActivitySharedAction.CloseDrawer -> drawerLayout.closeDrawer(GravityCompat.START) + is HomeActivitySharedAction.OpenDrawer -> views.drawerLayout.openDrawer(GravityCompat.START) + is HomeActivitySharedAction.CloseDrawer -> views.drawerLayout.closeDrawer(GravityCompat.START) is HomeActivitySharedAction.OpenGroup -> { - drawerLayout.closeDrawer(GravityCompat.START) + views.drawerLayout.closeDrawer(GravityCompat.START) replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true) } }.exhaustive @@ -197,24 +204,24 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet private fun renderState(state: HomeActivityViewState) { when (val status = state.initialSyncProgressServiceStatus) { is InitialSyncProgressService.Status.Idle -> { - waiting_view.isVisible = false + views.waitingView.root.isVisible = false } is InitialSyncProgressService.Status.Progressing -> { Timber.v("${getString(status.statusText)} ${status.percentProgress}") - waiting_view.setOnClickListener { + views.waitingView.root.setOnClickListener { // block interactions } - waitingHorizontalProgress.apply { + views.waitingView.waitingHorizontalProgress.apply { isIndeterminate = false max = 100 progress = status.percentProgress isVisible = true } - waitingStatusText.apply { + views.waitingView.waitingStatusText.apply { text = getString(status.statusText) isVisible = true } - waiting_view.isVisible = true + views.waitingView.root.isVisible = true } }.exhaustive } @@ -269,7 +276,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet ).apply { colorInt = ThemeUtils.getColor(this@HomeActivity, R.attr.vctr_notice_secondary) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity)?.let { + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { // action(it) homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed) it.navigator.openSettings(it, VectorSettingsActivity.EXTRA_DIRECT_ACCESS_NOTIFICATIONS) @@ -282,7 +289,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed) }, true) addButton(getString(R.string.settings), Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity)?.let { + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { // action(it) homeActivityViewModel.handle(HomeActivityViewActions.PushPromptHasBeenReviewed) it.navigator.openSettings(it, VectorSettingsActivity.EXTRA_DIRECT_ACCESS_NOTIFICATIONS) @@ -292,7 +299,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet ) } - private fun promptSecurityEvent(userItem: MatrixItem.UserItem?, titleRes: Int, descRes: Int, action: ((VectorBaseActivity) -> Unit)) { + private fun promptSecurityEvent(userItem: MatrixItem.UserItem?, titleRes: Int, descRes: Int, action: ((VectorBaseActivity<*>) -> Unit)) { popupAlertManager.postVectorAlert( VerificationVectorAlert( uid = "upgradeSecurity", @@ -303,7 +310,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet ).apply { colorInt = ContextCompat.getColor(this@HomeActivity, R.color.riotx_positive_accent) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity)?.let { + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { action(it) } } @@ -321,7 +328,7 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet } override fun onDestroy() { - drawerLayout.removeDrawerListener(drawerListener) + views.drawerLayout.removeDrawerListener(drawerListener) super.onDestroy() } @@ -375,8 +382,8 @@ class HomeActivity : VectorBaseActivity(), ToolbarConfigurable, UnknownDeviceDet } override fun onBackPressed() { - if (drawerLayout.isDrawerOpen(GravityCompat.START)) { - drawerLayout.closeDrawer(GravityCompat.START) + if (views.drawerLayout.isDrawerOpen(GravityCompat.START)) { + views.drawerLayout.closeDrawer(GravityCompat.START) } else { super.onBackPressed() } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index 1c63d63ae0..ff5dcb9156 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.home import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.lifecycle.Observer import com.airbnb.mvrx.activityViewModel @@ -33,6 +35,8 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.ui.views.ActiveCallView import im.vector.app.core.ui.views.ActiveCallViewHolder import im.vector.app.core.ui.views.KeysBackupBanner +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentHomeDetailBinding import im.vector.app.features.call.SharedActiveCallViewModel import im.vector.app.features.call.VectorCallActivity import im.vector.app.features.call.WebRtcPeerConnectionManager @@ -46,7 +50,7 @@ import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.workers.signout.BannerState import im.vector.app.features.workers.signout.ServerBackupStatusViewModel import im.vector.app.features.workers.signout.ServerBackupStatusViewState -import kotlinx.android.synthetic.main.fragment_home_detail.* + import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo @@ -64,7 +68,10 @@ class HomeDetailFragment @Inject constructor( private val alertManager: PopupAlertManager, private val webRtcPeerConnectionManager: WebRtcPeerConnectionManager, private val vectorPreferences: VectorPreferences -) : VectorBaseFragment(), KeysBackupBanner.Delegate, ActiveCallView.Callback, ServerBackupStatusViewModel.Factory { +) : VectorBaseFragment(), + KeysBackupBanner.Delegate, + ActiveCallView.Callback, + ServerBackupStatusViewModel.Factory { private val viewModel: HomeDetailViewModel by fragmentViewModel() private val unknownDeviceDetectorSharedViewModel: UnknownDeviceDetectorSharedViewModel by activityViewModel() @@ -73,7 +80,9 @@ class HomeDetailFragment @Inject constructor( private lateinit var sharedActionViewModel: HomeSharedActionViewModel private lateinit var sharedCallActionViewModel: SharedActiveCallViewModel - override fun getLayoutResId() = R.layout.fragment_home_detail + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDetailBinding { + return FragmentHomeDetailBinding.inflate(inflater, container, false) + } private val activeCallViewHolder = ActiveCallViewHolder() @@ -89,7 +98,7 @@ class HomeDetailFragment @Inject constructor( withState(viewModel) { // Update the navigation view if needed (for when we restore the tabs) - bottomNavigationView.selectedItemId = it.displayMode.toMenuId() + views.bottomNavigationView.selectedItemId = it.displayMode.toMenuId() } viewModel.selectSubscribe(this, HomeDetailViewState::groupSummary) { groupSummary -> @@ -132,8 +141,8 @@ class HomeDetailFragment @Inject constructor( } private fun checkNotificationTabStatus() { - val wasVisible = bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible - bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab() + val wasVisible = views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible + views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab() if (wasVisible && !vectorPreferences.labAddNotificationTab()) { // As we hide it check if it's not the current item! withState(viewModel) { @@ -156,7 +165,7 @@ class HomeDetailFragment @Inject constructor( ).apply { colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity) + (weakCurrentActivity?.get() as? VectorBaseActivity<*>) ?.navigator ?.requestSessionVerification(requireContext(), newest.deviceId ?: "") unknownDeviceDetectorSharedViewModel.handle( @@ -184,7 +193,7 @@ class HomeDetailFragment @Inject constructor( ).apply { colorInt = ContextCompat.getColor(requireActivity(), R.color.riotx_accent) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity)?.let { + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { // mark as ignored to avoid showing it again unknownDeviceDetectorSharedViewModel.handle( UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(oldUnverified.mapNotNull { it.deviceId }) @@ -204,7 +213,7 @@ class HomeDetailFragment @Inject constructor( private fun onGroupChange(groupSummary: GroupSummary?) { groupSummary?.let { // Use GlideApp with activity context to avoid the glideRequests to be paused - avatarRenderer.render(it.toMatrixItem(), groupToolbarAvatarImageView, GlideApp.with(requireActivity())) + avatarRenderer.render(it.toMatrixItem(), views.groupToolbarAvatarImageView, GlideApp.with(requireActivity())) } } @@ -212,20 +221,20 @@ class HomeDetailFragment @Inject constructor( serverBackupStatusViewModel .subscribe(this) { when (val banState = it.bannerState.invoke()) { - is BannerState.Setup -> homeKeysBackupBanner.render(KeysBackupBanner.State.Setup(banState.numberOfKeys), false) - BannerState.BackingUp -> homeKeysBackupBanner.render(KeysBackupBanner.State.BackingUp, false) + is BannerState.Setup -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.Setup(banState.numberOfKeys), false) + BannerState.BackingUp -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.BackingUp, false) null, - BannerState.Hidden -> homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false) + BannerState.Hidden -> views.homeKeysBackupBanner.render(KeysBackupBanner.State.Hidden, false) } } - homeKeysBackupBanner.delegate = this + views.homeKeysBackupBanner.delegate = this } private fun setupActiveCallView() { activeCallViewHolder.bind( - activeCallPiP, - activeCallView, - activeCallPiPWrap, + views.activeCallPiP, + views.activeCallView, + views.activeCallPiPWrap, this ) } @@ -233,17 +242,17 @@ class HomeDetailFragment @Inject constructor( private fun setupToolbar() { val parentActivity = vectorBaseActivity if (parentActivity is ToolbarConfigurable) { - parentActivity.configure(groupToolbar) + parentActivity.configure(views.groupToolbar) } - groupToolbar.title = "" - groupToolbarAvatarImageView.debouncedClicks { + views.groupToolbar.title = "" + views.groupToolbarAvatarImageView.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.OpenDrawer) } } private fun setupBottomNavigationView() { - bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab() - bottomNavigationView.setOnNavigationItemSelectedListener { + views.bottomNavigationView.menu.findItem(R.id.bottom_action_notification).isVisible = vectorPreferences.labAddNotificationTab() + views.bottomNavigationView.setOnNavigationItemSelectedListener { val displayMode = when (it.itemId) { R.id.bottom_action_people -> RoomListDisplayMode.PEOPLE R.id.bottom_action_rooms -> RoomListDisplayMode.ROOMS @@ -266,7 +275,7 @@ class HomeDetailFragment @Inject constructor( } private fun switchDisplayMode(displayMode: RoomListDisplayMode) { - groupToolbarTitleView.setText(displayMode.titleRes) + views.groupToolbarTitleView.setText(displayMode.titleRes) updateSelectedFragment(displayMode) } @@ -302,10 +311,10 @@ class HomeDetailFragment @Inject constructor( override fun invalidate() = withState(viewModel) { Timber.v(it.toString()) - bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople) - bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms) - bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup) - syncStateView.render(it.syncState) + views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_people).render(it.notificationCountPeople, it.notificationHighlightPeople) + views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms) + views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup) + views.syncStateView.render(it.syncState) } private fun BadgeDrawable.render(count: Int, highlight: Boolean) { diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt index 1a60d8e219..5271c0101f 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDrawerFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.home import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.app.ActivityOptionsCompat import androidx.core.view.ViewCompat import androidx.core.view.isVisible @@ -27,12 +29,14 @@ import im.vector.app.core.extensions.observeK import im.vector.app.core.extensions.replaceChildFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startSharePlainTextIntent +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentHomeDrawerBinding import im.vector.app.features.grouplist.GroupListFragment import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsActivity import im.vector.app.features.usercode.UserCodeActivity import im.vector.app.features.workers.signout.SignOutUiWorker -import kotlinx.android.synthetic.main.fragment_home_drawer.* + import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -41,11 +45,13 @@ class HomeDrawerFragment @Inject constructor( private val session: Session, private val vectorPreferences: VectorPreferences, private val avatarRenderer: AvatarRenderer -) : VectorBaseFragment() { +) : VectorBaseFragment() { private lateinit var sharedActionViewModel: HomeSharedActionViewModel - override fun getLayoutResId() = R.layout.fragment_home_drawer + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDrawerBinding { + return FragmentHomeDrawerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -58,40 +64,40 @@ class HomeDrawerFragment @Inject constructor( session.getUserLive(session.myUserId).observeK(viewLifecycleOwner) { optionalUser -> val user = optionalUser?.getOrNull() if (user != null) { - avatarRenderer.render(user.toMatrixItem(), homeDrawerHeaderAvatarView) - homeDrawerUsernameView.text = user.displayName - homeDrawerUserIdView.text = user.userId + avatarRenderer.render(user.toMatrixItem(), views.homeDrawerHeaderAvatarView) + views.homeDrawerUsernameView.text = user.displayName + views.homeDrawerUserIdView.text = user.userId } } // Profile - homeDrawerHeader.debouncedClicks { + views.homeDrawerHeader.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) navigator.openSettings(requireActivity(), directAccess = VectorSettingsActivity.EXTRA_DIRECT_ACCESS_GENERAL) } // Settings - homeDrawerHeaderSettingsView.debouncedClicks { + views.homeDrawerHeaderSettingsView.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) navigator.openSettings(requireActivity()) } // Sign out - homeDrawerHeaderSignoutView.debouncedClicks { + views.homeDrawerHeaderSignoutView.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) SignOutUiWorker(requireActivity()).perform() } - homeDrawerQRCodeButton.debouncedClicks { + views.homeDrawerQRCodeButton.debouncedClicks { UserCodeActivity.newIntent(requireContext(), sharedActionViewModel.session.myUserId).let { val options = ActivityOptionsCompat.makeSceneTransitionAnimation( requireActivity(), - homeDrawerHeaderAvatarView, - ViewCompat.getTransitionName(homeDrawerHeaderAvatarView) ?: "" + views.homeDrawerHeaderAvatarView, + ViewCompat.getTransitionName(views.homeDrawerHeaderAvatarView) ?: "" ) startActivity(it, options.toBundle()) } } - homeDrawerInviteFriendButton.debouncedClicks { + views.homeDrawerInviteFriendButton.debouncedClicks { session.permalinkService().createPermalink(sharedActionViewModel.session.myUserId)?.let { permalink -> val text = getString(R.string.invite_friends_text, permalink) @@ -106,8 +112,8 @@ class HomeDrawerFragment @Inject constructor( } // Debug menu - homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode() - homeDrawerHeaderDebugView.debouncedClicks { + views.homeDrawerHeaderDebugView.isVisible = BuildConfig.DEBUG && vectorPreferences.developerMode() + views.homeDrawerHeaderDebugView.debouncedClicks { sharedActionViewModel.post(HomeActivitySharedAction.CloseDrawer) navigator.openDebug(requireActivity()) } diff --git a/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt b/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt index e56887b85f..a5c9f1ad6a 100644 --- a/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/LoadingFragment.kt @@ -18,20 +18,26 @@ package im.vector.app.features.home import android.graphics.drawable.AnimationDrawable import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_loading.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoadingBinding + import javax.inject.Inject -class LoadingFragment @Inject constructor() : VectorBaseFragment() { +class LoadingFragment @Inject constructor() : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_loading + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoadingBinding { + return FragmentLoadingBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val background = animatedLogoImageView.background + val background = views.animatedLogoImageView.background if (background is AnimationDrawable) { background.start() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt index c147985809..de78afdaa8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/breadcrumbs/BreadcrumbsFragment.kt @@ -17,27 +17,34 @@ package im.vector.app.features.home.room.breadcrumbs import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentBreadcrumbsBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.home.room.detail.RoomDetailSharedAction import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel -import kotlinx.android.synthetic.main.fragment_breadcrumbs.* + import javax.inject.Inject class BreadcrumbsFragment @Inject constructor( private val breadcrumbsController: BreadcrumbsController, val breadcrumbsViewModelFactory: BreadcrumbsViewModel.Factory -) : VectorBaseFragment(), BreadcrumbsController.Listener { +) : VectorBaseFragment(), + BreadcrumbsController.Listener { private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel private val breadcrumbsViewModel: BreadcrumbsViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_breadcrumbs + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentBreadcrumbsBinding { + return FragmentBreadcrumbsBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -46,13 +53,13 @@ class BreadcrumbsFragment @Inject constructor( } override fun onDestroyView() { - breadcrumbsRecyclerView.cleanup() + views.breadcrumbsRecyclerView.cleanup() breadcrumbsController.listener = null super.onDestroyView() } private fun setupRecyclerView() { - breadcrumbsRecyclerView.configureWith(breadcrumbsController, BreadcrumbsAnimator(), hasFixedSize = false) + views.breadcrumbsRecyclerView.configureWith(breadcrumbsController, BreadcrumbsAnimator(), hasFixedSize = false) breadcrumbsController.listener = this } @@ -67,6 +74,6 @@ class BreadcrumbsFragment @Inject constructor( } fun scrollToTop() { - breadcrumbsRecyclerView.scrollToPosition(0) + views.breadcrumbsRecyclerView.scrollToPosition(0) } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index de82689303..9c2d5bafee 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -37,8 +37,8 @@ import im.vector.app.features.room.RequireActiveMembershipViewModel import im.vector.app.features.room.RequireActiveMembershipViewState import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState -import kotlinx.android.synthetic.main.activity_room_detail.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* + + import javax.inject.Inject class RoomDetailActivity : diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index 1a7a7ec359..03db33d5ac 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -167,10 +167,10 @@ import im.vector.app.features.widgets.WidgetKind import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_room_detail.* -import kotlinx.android.synthetic.main.composer_layout.view.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import kotlinx.parcelize.Parcelize + + + import nl.dionsegijn.konfetti.models.Shape import nl.dionsegijn.konfetti.models.Size import org.billcarsonfr.jsonviewer.JSonViewerDialog diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt index d48d994caa..427f30fc01 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/TextComposerView.kt @@ -31,7 +31,7 @@ import androidx.transition.Transition import androidx.transition.TransitionManager import androidx.transition.TransitionSet import im.vector.app.R -import kotlinx.android.synthetic.main.composer_layout.view.* + import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel /** diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt index bf3ee97f9e..52c9dbae00 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/readreceipts/DisplayReadReceiptsBottomSheet.kt @@ -18,7 +18,9 @@ package im.vector.app.features.home.room.detail.readreceipts import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.args import im.vector.app.R @@ -26,11 +28,13 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject @Parcelize @@ -41,7 +45,9 @@ data class DisplayReadReceiptArgs( /** * Bottom sheet displaying list of read receipts for a given event ordered by descending timestamp */ -class DisplayReadReceiptsBottomSheet : VectorBaseBottomSheetDialogFragment(), DisplayReadReceiptsController.Listener { +class DisplayReadReceiptsBottomSheet : + VectorBaseBottomSheetDialogFragment(), + DisplayReadReceiptsController.Listener { @Inject lateinit var epoxyController: DisplayReadReceiptsController @@ -53,19 +59,21 @@ class DisplayReadReceiptsBottomSheet : VectorBaseBottomSheetDialogFragment(), Di injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { + return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) - bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false) - bottomSheetTitle.text = getString(R.string.seen_by) + views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false) + views.bottomSheetTitle.text = getString(R.string.seen_by) epoxyController.listener = this epoxyController.setData(displayReadReceiptArgs.readReceipts) } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() epoxyController.listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt index f85dccbb27..8ee376702b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchActivity.kt @@ -19,22 +19,23 @@ package im.vector.app.features.home.room.detail.search import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import androidx.appcompat.widget.SearchView import com.airbnb.mvrx.MvRx import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.synthetic.main.activity_search.* +import im.vector.app.databinding.ActivitySearchBinding -class SearchActivity : VectorBaseActivity() { +class SearchActivity : VectorBaseActivity() { private val searchFragment: SearchFragment? get() { return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? SearchFragment } - override fun getLayoutRes() = R.layout.activity_search + override fun getBinding() = ActivitySearchBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { super.injectWith(injector) @@ -43,7 +44,7 @@ class SearchActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - configureToolbar(searchToolbar) + configureToolbar(views.searchToolbar) } override fun initUiAndData() { @@ -51,7 +52,7 @@ class SearchActivity : VectorBaseActivity() { val fragmentArgs: SearchArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG) ?: return addFragment(R.id.searchFragmentContainer, SearchFragment::class.java, fragmentArgs, FRAGMENT_TAG) } - searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + views.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { searchFragment?.search(query) return true @@ -62,7 +63,7 @@ class SearchActivity : VectorBaseActivity() { } }) // Open the keyboard immediately - searchView.requestFocus() + views.searchView.requestFocus() } companion object { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt index 201e9a4f82..47faf72a25 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/search/SearchFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.home.room.detail.search import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.recyclerview.widget.LinearLayoutManager import com.airbnb.mvrx.Fail @@ -34,8 +36,10 @@ import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_search.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentSearchBinding +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.session.events.model.Event import javax.inject.Inject @@ -47,32 +51,36 @@ data class SearchArgs( class SearchFragment @Inject constructor( val viewModelFactory: SearchViewModel.Factory, private val controller: SearchResultController -) : VectorBaseFragment(), StateView.EventCallback, SearchResultController.Listener { +) : VectorBaseFragment(), + StateView.EventCallback, + SearchResultController.Listener { private val fragmentArgs: SearchArgs by args() private val searchViewModel: SearchViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_search + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSearchBinding { + return FragmentSearchBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - stateView.contentView = searchResultRecycler - stateView.eventCallback = this + views.stateView.contentView = views.searchResultRecycler + views.stateView.eventCallback = this configureRecyclerView() } private fun configureRecyclerView() { - searchResultRecycler.trackItemsVisibilityChange() - searchResultRecycler.configureWith(controller, showDivider = false) - (searchResultRecycler.layoutManager as? LinearLayoutManager)?.stackFromEnd = true + views.searchResultRecycler.trackItemsVisibilityChange() + views.searchResultRecycler.configureWith(controller, showDivider = false) + (views.searchResultRecycler.layoutManager as? LinearLayoutManager)?.stackFromEnd = true controller.listener = this } override fun onDestroy() { super.onDestroy() - searchResultRecycler?.cleanup() + views.searchResultRecycler?.cleanup() controller.listener = null } @@ -80,20 +88,20 @@ class SearchFragment @Inject constructor( if (state.searchResult.isNullOrEmpty()) { when (state.asyncSearchRequest) { is Loading -> { - stateView.state = StateView.State.Loading + views.stateView.state = StateView.State.Loading } is Fail -> { - stateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncSearchRequest.error)) + views.stateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncSearchRequest.error)) } is Success -> { - stateView.state = StateView.State.Empty( + views.stateView.state = StateView.State.Empty( title = getString(R.string.search_no_results), image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_search_no_results)) } } } else { controller.setData(state) - stateView.state = StateView.State.Content + views.stateView.state = StateView.State.Content } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt index 81e9ffd24e..0b6df89989 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsBottomSheet.kt @@ -16,7 +16,9 @@ package im.vector.app.features.home.room.detail.timeline.action import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -24,14 +26,17 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* + import javax.inject.Inject /** * Bottom sheet fragment that shows a message preview with list of contextual actions */ -class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), MessageActionsEpoxyController.MessageActionsEpoxyControllerListener { +class MessageActionsBottomSheet : + VectorBaseBottomSheetDialogFragment(), + MessageActionsEpoxyController.MessageActionsEpoxyControllerListener { @Inject lateinit var messageActionViewModelFactory: MessageActionsViewModel.Factory @Inject lateinit var messageActionsEpoxyController: MessageActionsEpoxyController @@ -46,17 +51,19 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) - bottomSheetRecyclerView.configureWith(messageActionsEpoxyController, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetRecyclerView.configureWith(messageActionsEpoxyController, hasFixedSize = false, disableItemAnimation = true) messageActionsEpoxyController.listener = this } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() super.onDestroyView() } @@ -76,8 +83,8 @@ class MessageActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), Message if (eventAction is EventSharedAction.ReportContent) { // Toggle report menu // Enable item animation - if (bottomSheetRecyclerView.itemAnimator == null) { - bottomSheetRecyclerView.itemAnimator = MessageActionsAnimator() + if (views.bottomSheetRecyclerView.itemAnimator == null) { + views.bottomSheetRecyclerView.itemAnimator = MessageActionsAnimator() } viewModel.handle(MessageActionsAction.ToggleReportMenu) } else { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/TimelineEventFragmentArgs.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/TimelineEventFragmentArgs.kt index fcfd6cdb8d..1bb1a876bd 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/TimelineEventFragmentArgs.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/TimelineEventFragmentArgs.kt @@ -18,7 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.action import android.os.Parcelable import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class TimelineEventFragmentArgs( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt index 7a6bb412cc..376da4c650 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryBottomSheet.kt @@ -16,7 +16,9 @@ package im.vector.app.features.home.room.detail.timeline.edithistory import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -25,16 +27,19 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData import im.vector.app.features.html.EventHtmlRenderer -import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.* + import javax.inject.Inject /** * Bottom sheet displaying list of edits for a given event ordered by timestamp */ -class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() { +class ViewEditHistoryBottomSheet : + VectorBaseBottomSheetDialogFragment() { private val viewModel: ViewEditHistoryViewModel by fragmentViewModel(ViewEditHistoryViewModel::class) @@ -49,19 +54,21 @@ class ViewEditHistoryBottomSheet : VectorBaseBottomSheetDialogFragment() { injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { + return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.configureWith( + views.bottomSheetRecyclerView.configureWith( epoxyController, showDivider = true, hasFixedSize = false) - bottomSheetTitle.text = context?.getString(R.string.message_edits) + views.bottomSheetTitle.text = context?.getString(R.string.message_edits) } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt index b0fc293fda..38575f0cc9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt @@ -17,7 +17,7 @@ package im.vector.app.features.home.room.detail.timeline.item import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.internal.session.room.VerificationState diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt index be368682c1..d004d5b3c6 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/PollResultLineView.kt @@ -23,7 +23,7 @@ import android.widget.LinearLayout import androidx.core.content.withStyledAttributes import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide -import kotlinx.android.synthetic.main.item_timeline_event_poll_result_item.view.* + class PollResultLineView @JvmOverloads constructor( context: Context, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt index c1d71f4162..5cc4108e10 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/reactions/ViewReactionsBottomSheet.kt @@ -17,7 +17,9 @@ package im.vector.app.features.home.room.detail.timeline.reactions import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -26,17 +28,21 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.app.features.home.room.detail.timeline.action.TimelineEventFragmentArgs import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData -import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.* + import javax.inject.Inject /** * Bottom sheet displaying list of reactions for a given event ordered by timestamp */ -class ViewReactionsBottomSheet : VectorBaseBottomSheetDialogFragment(), ViewReactionsEpoxyController.Listener { +class ViewReactionsBottomSheet : + VectorBaseBottomSheetDialogFragment(), + ViewReactionsEpoxyController.Listener { private val viewModel: ViewReactionsViewModel by fragmentViewModel(ViewReactionsViewModel::class) @@ -49,18 +55,20 @@ class ViewReactionsBottomSheet : VectorBaseBottomSheetDialogFragment(), ViewReac injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { + return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(MessageSharedActionViewModel::class.java) - bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false, showDivider = true) - bottomSheetTitle.text = context?.getString(R.string.reactions) + views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false, showDivider = true) + views.bottomSheetTitle.text = context?.getString(R.string.reactions) epoxyController.listener = this } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() epoxyController.listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt index c69e47614c..01745e3f05 100755 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt @@ -25,7 +25,7 @@ import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.media.ImageContentRenderer -import kotlinx.android.synthetic.main.url_preview.view.* + import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.media.PreviewUrlData diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt index 7fe8b87fe0..f0289cedfa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBannerView.kt @@ -21,7 +21,7 @@ import android.util.AttributeSet import android.view.View import android.widget.RelativeLayout import im.vector.app.R -import kotlinx.android.synthetic.main.view_room_widgets_banner.view.* + import org.matrix.android.sdk.api.session.widgets.model.Widget class RoomWidgetsBannerView @JvmOverloads constructor( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt index 1799deae66..2bdde63beb 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/widget/RoomWidgetsBottomSheet.kt @@ -17,7 +17,9 @@ package im.vector.app.features.home.room.detail.widget import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -26,18 +28,22 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.RoomDetailViewModel import im.vector.app.features.home.room.detail.RoomDetailViewState import im.vector.app.features.navigation.Navigator -import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.* + import org.matrix.android.sdk.api.session.widgets.model.Widget import javax.inject.Inject /** * Bottom sheet displaying active widgets in a room */ -class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidgetsController.Listener { +class RoomWidgetsBottomSheet : + VectorBaseBottomSheetDialogFragment(), + RoomWidgetsController.Listener { @Inject lateinit var epoxyController: RoomWidgetsController @Inject lateinit var colorProvider: ColorProvider @@ -49,14 +55,16 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { + return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false) - bottomSheetTitle.text = getString(R.string.active_widgets_title) - bottomSheetTitle.textSize = 20f - bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)) + views.bottomSheetRecyclerView.configureWith(epoxyController, hasFixedSize = false) + views.bottomSheetTitle.text = getString(R.string.active_widgets_title) + views.bottomSheetTitle.textSize = 20f + views.bottomSheetTitle.setTextColor(colorProvider.getColorFromAttribute(R.attr.riotx_text_primary)) epoxyController.listener = this roomDetailViewModel.asyncSubscribe(this, RoomDetailViewState::activeRoomWidgets) { epoxyController.setData(it) @@ -64,7 +72,7 @@ class RoomWidgetsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomWidget } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() epoxyController.listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt index ee33b4339c..4158256a76 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/filtered/FilteredRoomsActivity.kt @@ -19,24 +19,26 @@ package im.vector.app.features.home.room.filtered import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import androidx.appcompat.widget.SearchView import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityFilteredRoomsBinding import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.RoomListFragment import im.vector.app.features.home.room.list.RoomListParams -import kotlinx.android.synthetic.main.activity_filtered_rooms.* -class FilteredRoomsActivity : VectorBaseActivity() { + +class FilteredRoomsActivity : VectorBaseActivity() { private val roomListFragment: RoomListFragment? get() { return supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as? RoomListFragment } - override fun getLayoutRes() = R.layout.activity_filtered_rooms + override fun getBinding() = ActivityFilteredRoomsBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -44,12 +46,12 @@ class FilteredRoomsActivity : VectorBaseActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - configureToolbar(filteredRoomsToolbar) + configureToolbar(views.filteredRoomsToolbar) if (isFirstCreation()) { val params = RoomListParams(RoomListDisplayMode.FILTERED) replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG) } - filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + views.filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { return true } @@ -60,7 +62,7 @@ class FilteredRoomsActivity : VectorBaseActivity() { } }) // Open the keyboard immediately - filteredRoomsSearchView.requestFocus() + views.filteredRoomsSearchView.requestFocus() } companion object { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt index b4f525c119..300b38ee17 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt @@ -18,9 +18,11 @@ package im.vector.app.features.home.room.list import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.content.ContextCompat import androidx.core.view.isVisible @@ -40,6 +42,8 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomListBinding import im.vector.app.features.home.RoomListDisplayMode import im.vector.app.features.home.room.list.actions.RoomListActionsArgs import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet @@ -47,8 +51,8 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.home.room.list.widget.NotifsFabMenuView import im.vector.app.features.notifications.NotificationDrawerManager -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_room_list.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -66,7 +70,10 @@ class RoomListFragment @Inject constructor( val roomListViewModelFactory: RoomListViewModel.Factory, private val notificationDrawerManager: NotificationDrawerManager, private val sharedViewPool: RecyclerView.RecycledViewPool -) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, NotifsFabMenuView.Listener { +) : VectorBaseFragment(), + RoomSummaryController.Listener, + OnBackPressed, + NotifsFabMenuView.Listener { private var modelBuildListener: OnModelBuildFinishedListener? = null private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @@ -74,7 +81,9 @@ class RoomListFragment @Inject constructor( private val roomListViewModel: RoomListViewModel by fragmentViewModel() private lateinit var stateRestorer: LayoutManagerStateRestorer - override fun getLayoutResId() = R.layout.fragment_room_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomListBinding { + return FragmentRoomListBinding.inflate(inflater, container, false) + } private var hasUnreadRooms = false diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt index 306e951ab8..baa7057741 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt @@ -18,7 +18,9 @@ package im.vector.app.features.home.room.list.actions import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -27,9 +29,10 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding import im.vector.app.features.navigation.Navigator -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject @Parcelize @@ -47,7 +50,9 @@ data class RoomListActionsArgs( /** * Bottom sheet fragment that shows room information with list of contextual actions */ -class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomListQuickActionsEpoxyController.Listener { +class RoomListQuickActionsBottomSheet : + VectorBaseBottomSheetDialogFragment(), + RoomListQuickActionsEpoxyController.Listener { private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool @@ -63,17 +68,19 @@ class RoomListQuickActionsBottomSheet : VectorBaseBottomSheetDialogFragment(), R injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(RoomListQuickActionsSharedActionViewModel::class.java) - bottomSheetRecyclerView.configureWith(roomListActionsEpoxyController, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) + views.views.bottomSheetRecyclerView.configureWith(roomListActionsEpoxyController, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) roomListActionsEpoxyController.listener = this } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.views.bottomSheetRecyclerView.cleanup() roomListActionsEpoxyController.listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/widget/NotifsFabMenuView.kt b/vector/src/main/java/im/vector/app/features/home/room/list/widget/NotifsFabMenuView.kt index 7c96f40dbf..b196e0d670 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/widget/NotifsFabMenuView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/widget/NotifsFabMenuView.kt @@ -22,7 +22,7 @@ import androidx.constraintlayout.motion.widget.MotionLayout import androidx.core.view.isVisible import com.google.android.material.floatingactionbutton.FloatingActionButton import im.vector.app.R -import kotlinx.android.synthetic.main.motion_notifs_fab_menu_merge.view.* + class NotifsFabMenuView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : MotionLayout(context, attrs, defStyleAttr) { diff --git a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt index 65f547a662..f00899d7f0 100644 --- a/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/invite/InviteUsersToRoomActivity.kt @@ -45,8 +45,8 @@ import im.vector.app.features.userdirectory.UserListSharedAction import im.vector.app.features.userdirectory.UserListSharedActionViewModel import im.vector.app.features.userdirectory.UserListViewModel import im.vector.app.features.userdirectory.UserListViewState -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.failure.Failure import java.net.HttpURLConnection import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt index 5e8c5b3cca..f8d4061e01 100644 --- a/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt +++ b/vector/src/main/java/im/vector/app/features/invite/VectorInviteView.kt @@ -19,13 +19,15 @@ package im.vector.app.features.invite import android.content.Context import android.util.AttributeSet import android.view.View +import android.widget.ImageView +import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.updateLayoutParams import im.vector.app.R import im.vector.app.core.di.HasScreenInjector import im.vector.app.core.platform.ButtonStateView import im.vector.app.features.home.AvatarRenderer -import kotlinx.android.synthetic.main.vector_invite_view.view.* + import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem @@ -44,6 +46,13 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib SMALL } + private val inviteAvatarView: ImageView + private val inviteLabelView: TextView + private val inviteNameView: TextView + private val inviteIdentifierView: TextView + private val inviteAcceptView: ButtonStateView + private val inviteRejectView: ButtonStateView + @Inject lateinit var avatarRenderer: AvatarRenderer var callback: Callback? = null @@ -52,6 +61,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib context.injector().inject(this) } View.inflate(context, R.layout.vector_invite_view, this) + inviteAcceptView = findViewById(R.id.inviteAcceptView) inviteAcceptView.callback = object : ButtonStateView.Callback { override fun onButtonClicked() { callback?.onAcceptInvite() @@ -62,6 +72,7 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib } } + inviteRejectView = findViewById(R.id.inviteRejectView) inviteRejectView.callback = object : ButtonStateView.Callback { override fun onButtonClicked() { callback?.onRejectInvite() @@ -71,6 +82,11 @@ class VectorInviteView @JvmOverloads constructor(context: Context, attrs: Attrib callback?.onRejectInvite() } } + + inviteAvatarView = findViewById(R.id.inviteAvatarView) + inviteLabelView = findViewById(R.id.inviteLabelView) + inviteNameView = findViewById(R.id.inviteNameView) + inviteIdentifierView = findViewById(R.id.inviteIdentifierView) } fun render(sender: RoomMemberSummary, mode: Mode = Mode.LARGE, changeMembershipState: ChangeMembershipState) { diff --git a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt index 78cf2d9a62..729aa860d3 100644 --- a/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/link/LinkHandlerActivity.kt @@ -18,6 +18,7 @@ package im.vector.app.features.link import android.content.Intent import android.net.Uri +import android.view.LayoutInflater import androidx.appcompat.app.AlertDialog import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder @@ -25,6 +26,7 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.toast +import im.vector.app.databinding.ActivityProgressBinding import im.vector.app.features.login.LoginActivity import im.vector.app.features.login.LoginConfig import im.vector.app.features.permalink.PermalinkHandler @@ -38,7 +40,7 @@ import javax.inject.Inject /** * Dummy activity used to dispatch the vector URL links. */ -class LinkHandlerActivity : VectorBaseActivity() { +class LinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var sessionHolder: ActiveSessionHolder @Inject lateinit var errorFormatter: ErrorFormatter @@ -48,7 +50,7 @@ class LinkHandlerActivity : VectorBaseActivity() { injector.inject(this) } - override fun getLayoutRes() = R.layout.activity_progress + override fun getBinding() = ActivityProgressBinding.inflate(layoutInflater) override fun initUiAndData() { val uri = intent.data diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt index e3c1aa7b12..e537f31e78 100644 --- a/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/AbstractLoginFragment.kt @@ -21,6 +21,7 @@ import android.view.View import androidx.annotation.CallSuper import androidx.appcompat.app.AlertDialog import androidx.transition.TransitionInflater +import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -35,7 +36,7 @@ import javax.net.ssl.HttpsURLConnection /** * Parent Fragment for all the login/registration screens */ -abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed { +abstract class AbstractLoginFragment : VectorBaseFragment(), OnBackPressed { protected val loginViewModel: LoginViewModel by activityViewModel() diff --git a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt index 9b0a154100..c20f4ddd23 100644 --- a/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/AbstractSSOLoginFragment.kt @@ -21,10 +21,11 @@ import android.net.Uri import androidx.browser.customtabs.CustomTabsClient import androidx.browser.customtabs.CustomTabsServiceConnection import androidx.browser.customtabs.CustomTabsSession +import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.withState import im.vector.app.core.utils.openUrlInChromeCustomTab -abstract class AbstractSSOLoginFragment : AbstractLoginFragment() { +abstract class AbstractSSOLoginFragment : AbstractLoginFragment() { // For sso private var customTabsServiceConnection: CustomTabsServiceConnection? = null diff --git a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt index 2e60fea660..99adda7b45 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginActivity.kt @@ -18,6 +18,7 @@ package im.vector.app.features.login import android.content.Context import android.content.Intent +import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.annotation.CallSuper @@ -39,12 +40,13 @@ import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityLoginBinding import im.vector.app.features.home.HomeActivity import im.vector.app.features.login.terms.LoginTermsFragment import im.vector.app.features.login.terms.LoginTermsFragmentArgument import im.vector.app.features.login.terms.toLocalizedLoginTerms import im.vector.app.features.pin.UnlockedActivity -import kotlinx.android.synthetic.main.activity_login.* + import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull @@ -53,7 +55,7 @@ import javax.inject.Inject /** * The LoginActivity manages the fragment navigation and also display the loading View */ -open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { +open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { private val loginViewModel: LoginViewModel by viewModel() @@ -84,7 +86,7 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedAc ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim) } - final override fun getLayoutRes() = R.layout.activity_login + final override fun getBinding() = ActivityLoginBinding.inflate(layoutInflater) override fun initUiAndData() { if (isFirstCreation()) { @@ -211,7 +213,7 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedAc } // Loading - loginLoading.isVisible = loginViewState.isLoading() + views.loginLoading.isVisible = loginViewState.isLoading() } private fun onWebLoginError(onWebLoginError: LoginViewEvents.OnWebLoginError) { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt index 6dd17a7d58..b01421d59b 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt @@ -23,6 +23,8 @@ import android.net.http.SslError import android.os.Build import android.os.Parcelable import android.view.KeyEvent +import android.view.LayoutInflater +import android.view.ViewGroup import android.webkit.SslErrorHandler import android.webkit.WebResourceRequest import android.webkit.WebResourceResponse @@ -33,8 +35,10 @@ import androidx.core.view.isVisible import com.airbnb.mvrx.args import im.vector.app.R import im.vector.app.core.utils.AssetReader -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_login_captcha.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginCaptchaBinding +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber import java.net.URLDecoder @@ -51,9 +55,11 @@ data class LoginCaptchaFragmentArgument( */ class LoginCaptchaFragment @Inject constructor( private val assetReader: AssetReader -) : AbstractLoginFragment() { +) : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_captcha + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginCaptchaBinding { + return FragmentLoginCaptchaBinding.inflate(inflater, container, false) + } private val params: LoginCaptchaFragmentArgument by args() @@ -61,7 +67,7 @@ class LoginCaptchaFragment @Inject constructor( @SuppressLint("SetJavaScriptEnabled") private fun setupWebView(state: LoginViewState) { - loginCaptchaWevView.settings.javaScriptEnabled = true + views.loginCaptchaWevView.settings.javaScriptEnabled = true val reCaptchaPage = assetReader.readAssetFile("reCaptchaPage.html") ?: error("missing asset reCaptchaPage.html") @@ -70,10 +76,10 @@ class LoginCaptchaFragment @Inject constructor( val encoding = "utf-8" val homeServerUrl = state.homeServerUrl ?: error("missing url of homeserver") - loginCaptchaWevView.loadDataWithBaseURL(homeServerUrl, html, mime, encoding, null) - loginCaptchaWevView.requestLayout() + views.loginCaptchaWevView.loadDataWithBaseURL(homeServerUrl, html, mime, encoding, null) + views.loginCaptchaWevView.requestLayout() - loginCaptchaWevView.webViewClient = object : WebViewClient() { + views.loginCaptchaWevView.webViewClient = object : WebViewClient() { override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) @@ -82,7 +88,7 @@ class LoginCaptchaFragment @Inject constructor( } // Show loader - loginCaptchaProgress.isVisible = true + views.loginCaptchaProgress.isVisible = true } override fun onPageFinished(view: WebView, url: String) { @@ -93,7 +99,7 @@ class LoginCaptchaFragment @Inject constructor( } // Hide loader - loginCaptchaProgress.isVisible = false + views.loginCaptchaProgress.isVisible = false } override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt b/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt index 47ce99754f..9c02ebae44 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginConfig.kt @@ -18,7 +18,7 @@ package im.vector.app.features.login import android.net.Uri import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize /** * Parameters extracted from a configuration url diff --git a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt index 9cb3428c80..ba89b981de 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.login import android.os.Build import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import androidx.autofill.HintConstants import androidx.core.text.isDigitsOnly @@ -32,11 +34,13 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.showPassword import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.FragmentLoginBinding import io.reactivex.Observable import io.reactivex.functions.BiFunction import io.reactivex.rxkotlin.subscribeBy -import kotlinx.android.synthetic.main.fragment_login.* -import kotlinx.android.synthetic.main.fragment_login_signup_signin_selection.* + + import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.failure.isInvalidPassword @@ -50,7 +54,7 @@ import javax.inject.Inject * In signup mode: * - the user is asked for login and password */ -class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { +class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { private var passwordShown = false private var isSignupMode = false @@ -59,7 +63,9 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { // waiting for https://github.com/matrix-org/synapse/issues/7576 private var isNumericOnlyUserIdForbidden = false - override fun getLayoutResId() = R.layout.fragment_login + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginBinding { + return FragmentLoginBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -68,7 +74,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { setupForgottenPasswordButton() setupPasswordReveal() - passwordField.setOnEditorActionListener { _, actionId, _ -> + views.passwordField.setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { submit() return@setOnEditorActionListener true @@ -78,7 +84,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { } private fun setupForgottenPasswordButton() { - forgetPasswordButton.setOnClickListener { forgetPasswordClicked() } + views.forgetPasswordButton.setOnClickListener { forgetPasswordClicked() } } private fun setupAutoFill(state: LoginViewState) { @@ -86,15 +92,15 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { when (state.signMode) { SignMode.Unknown -> error("developer error") SignMode.SignUp -> { - loginField.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME) - passwordField.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD) - loginSocialLoginButtons.mode = SocialLoginButtonsView.Mode.MODE_SIGN_UP + views.loginField.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_USERNAME) + views.passwordField.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD) + views.loginSocialLoginButtons.mode = SocialLoginButtonsView.Mode.MODE_SIGN_UP } SignMode.SignIn, SignMode.SignInWithMatrixId -> { - loginField.setAutofillHints(HintConstants.AUTOFILL_HINT_USERNAME) - passwordField.setAutofillHints(HintConstants.AUTOFILL_HINT_PASSWORD) - loginSocialLoginButtons.mode = SocialLoginButtonsView.Mode.MODE_SIGN_IN + views.loginField.setAutofillHints(HintConstants.AUTOFILL_HINT_USERNAME) + views.passwordField.setAutofillHints(HintConstants.AUTOFILL_HINT_PASSWORD) + views.loginSocialLoginButtons.mode = SocialLoginButtonsView.Mode.MODE_SIGN_IN } }.exhaustive } @@ -103,21 +109,21 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { private fun submit() { cleanupUi() - val login = loginField.text.toString() - val password = passwordField.text.toString() + val login = views.loginField.text.toString() + val password = views.passwordField.text.toString() // This can be called by the IME action, so deal with empty cases var error = 0 if (login.isEmpty()) { - loginFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_user_name else R.string.error_empty_field_enter_user_name) + views.loginFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_user_name else R.string.error_empty_field_enter_user_name) error++ } if (isSignupMode && isNumericOnlyUserIdForbidden && login.isDigitsOnly()) { - loginFieldTil.error = "The homeserver does not accept username with only digits." + views.loginFieldTil.error = "The homeserver does not accept username with only digits." error++ } if (password.isEmpty()) { - passwordFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_password else R.string.error_empty_field_your_password) + views.passwordFieldTil.error = getString(if (isSignupMode) R.string.error_empty_field_choose_password else R.string.error_empty_field_your_password) error++ } @@ -127,13 +133,13 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { } private fun cleanupUi() { - loginSubmit.hideKeyboard() - loginFieldTil.error = null - passwordFieldTil.error = null + views.loginSubmit.hideKeyboard() + views.loginFieldTil.error = null + views.passwordFieldTil.error = null } private fun setupUi(state: LoginViewState) { - loginFieldTil.hint = getString(when (state.signMode) { + views.loginFieldTil.hint = getString(when (state.signMode) { SignMode.Unknown -> error("developer error") SignMode.SignUp -> R.string.login_signup_username_hint SignMode.SignIn -> R.string.login_signin_username_hint @@ -142,10 +148,10 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { // Handle direct signin first if (state.signMode == SignMode.SignInWithMatrixId) { - loginServerIcon.isVisible = false - loginTitle.text = getString(R.string.login_signin_matrix_id_title) - loginNotice.text = getString(R.string.login_signin_matrix_id_notice) - loginPasswordNotice.isVisible = true + views.loginServerIcon.isVisible = false + views.loginTitle.text = getString(R.string.login_signin_matrix_id_title) + views.loginNotice.text = getString(R.string.login_signin_matrix_id_notice) + views.loginPasswordNotice.isVisible = true } else { val resId = when (state.signMode) { SignMode.Unknown -> error("developer error") @@ -156,45 +162,45 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { when (state.serverType) { ServerType.MatrixOrg -> { - loginServerIcon.isVisible = true - loginServerIcon.setImageResource(R.drawable.ic_logo_matrix_org) - loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl()) - loginNotice.text = getString(R.string.login_server_matrix_org_text) + views.loginServerIcon.isVisible = true + views.loginServerIcon.setImageResource(R.drawable.ic_logo_matrix_org) + views.loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl()) + views.loginNotice.text = getString(R.string.login_server_matrix_org_text) } ServerType.EMS -> { - loginServerIcon.isVisible = true - loginServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) - loginTitle.text = getString(resId, "Element Matrix Services") - loginNotice.text = getString(R.string.login_server_modular_text) + views.loginServerIcon.isVisible = true + views.loginServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) + views.loginTitle.text = getString(resId, "Element Matrix Services") + views.loginNotice.text = getString(R.string.login_server_modular_text) } ServerType.Other -> { - loginServerIcon.isVisible = false - loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl()) - loginNotice.text = getString(R.string.login_server_other_text) + views.loginServerIcon.isVisible = false + views.loginTitle.text = getString(resId, state.homeServerUrl.toReducedUrl()) + views.loginNotice.text = getString(R.string.login_server_other_text) } ServerType.Unknown -> Unit /* Should not happen */ } - loginPasswordNotice.isVisible = false + views.loginPasswordNotice.isVisible = false if (state.loginMode is LoginMode.SsoAndPassword) { - loginSocialLoginContainer.isVisible = true - loginSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders - loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { + views.loginSocialLoginContainer.isVisible = true + views.loginSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders + views.loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { override fun onProviderSelected(id: String?) { openInCustomTab(state.getSsoUrl(id)) } } } else { - loginSocialLoginContainer.isVisible = false - loginSocialLoginButtons.ssoIdentityProviders = null + views.loginSocialLoginContainer.isVisible = false + views.loginSocialLoginButtons.ssoIdentityProviders = null } } } private fun setupButtons(state: LoginViewState) { - forgetPasswordButton.isVisible = state.signMode == SignMode.SignIn + views.forgetPasswordButton.isVisible = state.signMode == SignMode.SignIn - loginSubmit.text = getString(when (state.signMode) { + views.loginSubmit.text = getString(when (state.signMode) { SignMode.Unknown -> error("developer error") SignMode.SignUp -> R.string.login_signup_submit SignMode.SignIn, @@ -203,19 +209,19 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { } private fun setupSubmitButton() { - loginSubmit.setOnClickListener { submit() } + views.loginSubmit.setOnClickListener { submit() } Observable .combineLatest( - loginField.textChanges().map { it.trim().isNotEmpty() }, - passwordField.textChanges().map { it.isNotEmpty() }, + views.loginField.textChanges().map { it.trim().isNotEmpty() }, + views.passwordField.textChanges().map { it.isNotEmpty() }, BiFunction { isLoginNotEmpty, isPasswordNotEmpty -> isLoginNotEmpty && isPasswordNotEmpty } ) .subscribeBy { - loginFieldTil.error = null - passwordFieldTil.error = null - loginSubmit.isEnabled = it + views.loginFieldTil.error = null + views.passwordFieldTil.error = null + views.loginSubmit.isEnabled = it } .disposeOnDestroyView() } @@ -227,7 +233,7 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { private fun setupPasswordReveal() { passwordShown = false - passwordReveal.setOnClickListener { + views.passwordReveal.setOnClickListener { passwordShown = !passwordShown renderPasswordField() @@ -237,14 +243,14 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { } private fun renderPasswordField() { - passwordField.showPassword(passwordShown) + views.passwordField.showPassword(passwordShown) if (passwordShown) { - passwordReveal.setImageResource(R.drawable.ic_eye_closed) - passwordReveal.contentDescription = getString(R.string.a11y_hide_password) + views.passwordReveal.setImageResource(R.drawable.ic_eye_closed) + views.passwordReveal.contentDescription = getString(R.string.a11y_hide_password) } else { - passwordReveal.setImageResource(R.drawable.ic_eye) - passwordReveal.contentDescription = getString(R.string.a11y_show_password) + views.passwordReveal.setImageResource(R.drawable.ic_eye) + views.passwordReveal.contentDescription = getString(R.string.a11y_show_password) } } @@ -256,9 +262,9 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { // Show M_WEAK_PASSWORD error in the password field if (throwable is Failure.ServerError && throwable.error.code == MatrixError.M_WEAK_PASSWORD) { - passwordFieldTil.error = errorFormatter.toHumanReadable(throwable) + views.passwordFieldTil.error = errorFormatter.toHumanReadable(throwable) } else { - loginFieldTil.error = errorFormatter.toHumanReadable(throwable) + views.loginFieldTil.error = errorFormatter.toHumanReadable(throwable) } } @@ -282,14 +288,14 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { && error.error.code == MatrixError.M_FORBIDDEN && error.error.message.isEmpty()) { // Login with email, but email unknown - loginFieldTil.error = getString(R.string.login_login_with_email_error) + views.loginFieldTil.error = getString(R.string.login_login_with_email_error) } else { // Trick to display the error without text. - loginFieldTil.error = " " + views.loginFieldTil.error = " " if (error.isInvalidPassword() && spaceInPassword()) { - passwordFieldTil.error = getString(R.string.auth_invalid_login_param_space_in_password) + views.passwordFieldTil.error = getString(R.string.auth_invalid_login_param_space_in_password) } else { - passwordFieldTil.error = errorFormatter.toHumanReadable(error) + views.passwordFieldTil.error = errorFormatter.toHumanReadable(error) } } } @@ -311,5 +317,5 @@ class LoginFragment @Inject constructor() : AbstractSSOLoginFragment() { /** * Detect if password ends or starts with spaces */ - private fun spaceInPassword() = passwordField.text.toString().let { it.trim() != it } + private fun spaceInPassword() = views.passwordField.text.toString().let { it.trim() != it } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginGenericTextInputFormFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginGenericTextInputFormFragment.kt index 70ef97c209..220577f2a2 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginGenericTextInputFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginGenericTextInputFormFragment.kt @@ -20,7 +20,9 @@ import android.os.Build import android.os.Bundle import android.os.Parcelable import android.text.InputType +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.autofill.HintConstants import androidx.core.view.isVisible import com.airbnb.mvrx.args @@ -31,8 +33,10 @@ import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.setTextOrHide -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_login_generic_text_input_form.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginGenericTextInputFormBinding +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.is401 @@ -54,11 +58,13 @@ data class LoginGenericTextInputFormFragmentArgument( /** * In this screen, the user is asked for a text input */ -class LoginGenericTextInputFormFragment @Inject constructor() : AbstractLoginFragment() { +class LoginGenericTextInputFormFragment @Inject constructor() : AbstractLoginFragment() { private val params: LoginGenericTextInputFormFragmentArgument by args() - override fun getLayoutResId() = R.layout.fragment_login_generic_text_input_form + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginGenericTextInputFormBinding { + return FragmentLoginGenericTextInputFormBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginMode.kt b/vector/src/main/java/im/vector/app/features/login/LoginMode.kt index 14accefc00..2be198ab96 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginMode.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginMode.kt @@ -17,7 +17,7 @@ package im.vector.app.features.login import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider sealed class LoginMode : Parcelable diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt index 5b6fc362cd..1fb738710e 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading @@ -28,23 +30,27 @@ import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.isEmail import im.vector.app.core.extensions.showPassword import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginResetPasswordBinding import io.reactivex.Observable import io.reactivex.functions.BiFunction import io.reactivex.rxkotlin.subscribeBy -import kotlinx.android.synthetic.main.fragment_login_reset_password.* + import javax.inject.Inject /** * In this screen, the user is asked for email and new password to reset his password */ -class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment() { +class LoginResetPasswordFragment @Inject constructor() : AbstractLoginFragment() { private var passwordShown = false // Show warning only once private var showWarning = true - override fun getLayoutResId() = R.layout.fragment_login_reset_password + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginResetPasswordBinding { + return FragmentLoginResetPasswordBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt index 08678c020c..14f2261874 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordMailConfirmationFragment.kt @@ -17,30 +17,36 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Success import im.vector.app.R -import kotlinx.android.synthetic.main.fragment_login_reset_password_mail_confirmation.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginResetPasswordMailConfirmationBinding + import org.matrix.android.sdk.api.failure.is401 import javax.inject.Inject /** * In this screen, the user is asked to check his email and to click on a button once it's done */ -class LoginResetPasswordMailConfirmationFragment @Inject constructor() : AbstractLoginFragment() { +class LoginResetPasswordMailConfirmationFragment @Inject constructor() : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_reset_password_mail_confirmation + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginResetPasswordMailConfirmationBinding { + return FragmentLoginResetPasswordMailConfirmationBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - resetPasswordMailConfirmationSubmit.setOnClickListener { submit() } + views.resetPasswordMailConfirmationSubmit.setOnClickListener { submit() } } private fun setupUi(state: LoginViewState) { - resetPasswordMailConfirmationNotice.text = getString(R.string.login_reset_password_mail_confirmation_notice, state.resetPasswordEmail) + views.resetPasswordMailConfirmationNotice.text = getString(R.string.login_reset_password_mail_confirmation_notice, state.resetPasswordEmail) } private fun submit() { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt index 1a428f57df..6dea50bbd2 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginResetPasswordSuccessFragment.kt @@ -17,22 +17,29 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import im.vector.app.R -import kotlinx.android.synthetic.main.fragment_login_reset_password_success.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginResetPasswordBinding +import im.vector.app.databinding.FragmentLoginResetPasswordSuccessBinding + import javax.inject.Inject /** * In this screen, we confirm to the user that his password has been reset */ -class LoginResetPasswordSuccessFragment @Inject constructor() : AbstractLoginFragment() { +class LoginResetPasswordSuccessFragment @Inject constructor() : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_reset_password_success + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginResetPasswordSuccessBinding { + return FragmentLoginResetPasswordSuccessBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - resetPasswordSuccessSubmit.setOnClickListener { submit() } + views.resetPasswordSuccessSubmit.setOnClickListener { submit() } } private fun submit() { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt index c365844c6e..13430fe241 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerSelectionFragment.kt @@ -17,19 +17,25 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import im.vector.app.R import im.vector.app.core.utils.openUrlInChromeCustomTab -import kotlinx.android.synthetic.main.fragment_login_server_selection.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginServerSelectionBinding + import me.gujun.android.span.span import javax.inject.Inject /** * In this screen, the user will choose between matrix.org, modular or other type of homeserver */ -class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment() { +class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_server_selection + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerSelectionBinding { + return FragmentLoginServerSelectionBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -39,19 +45,19 @@ class LoginServerSelectionFragment @Inject constructor() : AbstractLoginFragment } private fun initViews() { - loginServerChoiceEmsLearnMore.setOnClickListener { learnMore() } - loginServerChoiceMatrixOrg.setOnClickListener { selectMatrixOrg() } - loginServerChoiceEms.setOnClickListener { selectEMS() } - loginServerChoiceOther.setOnClickListener { selectOther() } - loginServerIKnowMyIdSubmit.setOnClickListener { loginWithMatrixId() } + views.loginServerChoiceEmsLearnMore.setOnClickListener { learnMore() } + views.loginServerChoiceMatrixOrg.setOnClickListener { selectMatrixOrg() } + views.loginServerChoiceEms.setOnClickListener { selectEMS() } + views.loginServerChoiceOther.setOnClickListener { selectOther() } + views.loginServerIKnowMyIdSubmit.setOnClickListener { loginWithMatrixId() } } private fun updateSelectedChoice(state: LoginViewState) { - loginServerChoiceMatrixOrg.isChecked = state.serverType == ServerType.MatrixOrg + views.loginServerChoiceMatrixOrg.isChecked = state.serverType == ServerType.MatrixOrg } private fun initTextViews() { - loginServerChoiceEmsLearnMore.text = span { + views.loginServerChoiceEmsLearnMore.text = span { text = getString(R.string.login_server_modular_learn_more) textDecorationLine = "underline" } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt index 7a4d60a2bd..2bc969e15f 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginServerUrlFormFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.login import android.annotation.SuppressLint import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.view.inputmethod.EditorInfo import android.widget.ArrayAdapter import androidx.core.view.isInvisible @@ -30,7 +32,9 @@ import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.utils.ensureProtocol import im.vector.app.core.utils.openUrlInChromeCustomTab -import kotlinx.android.synthetic.main.fragment_login_server_url_form.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginServerUrlFormBinding + import org.matrix.android.sdk.api.failure.Failure import java.net.UnknownHostException import javax.inject.Inject @@ -38,9 +42,11 @@ import javax.inject.Inject /** * In this screen, the user is prompted to enter a homeserver url */ -class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() { +class LoginServerUrlFormFragment @Inject constructor() : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_server_url_form + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginServerUrlFormBinding { + return FragmentLoginServerUrlFormBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt index 36ef6eef61..072428170e 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginSignUpSignInSelectionFragment.kt @@ -17,20 +17,26 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.toReducedUrl -import kotlinx.android.synthetic.main.fragment_login_signup_signin_selection.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginSignupSigninSelectionBinding + import javax.inject.Inject /** * In this screen, the user is asked to sign up or to sign in to the homeserver */ -class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLoginFragment() { +class LoginSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_signup_signin_selection + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSignupSigninSelectionBinding { + return FragmentLoginSignupSigninSelectionBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt index 7cb3e30810..c6927b4611 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginSplashFragment.kt @@ -17,17 +17,23 @@ package im.vector.app.features.login import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import im.vector.app.R -import kotlinx.android.synthetic.main.fragment_login_splash.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginSplashBinding + import javax.inject.Inject /** * In this screen, the user is viewing an introduction to what he can do with this application */ -class LoginSplashFragment @Inject constructor() : AbstractLoginFragment() { +class LoginSplashFragment @Inject constructor() : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_splash + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginSplashBinding { + return FragmentLoginSplashBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -36,7 +42,7 @@ class LoginSplashFragment @Inject constructor() : AbstractLoginFragment() { } private fun setupViews() { - loginSplashSubmit.setOnClickListener { getStarted() } + views.loginSplashSubmit.setOnClickListener { getStarted() } } private fun getStarted() { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWaitForEmailFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWaitForEmailFragment.kt index 6f86f1c9d6..ac19d595d6 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWaitForEmailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWaitForEmailFragment.kt @@ -18,11 +18,15 @@ package im.vector.app.features.login import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.args import im.vector.app.R -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_login_wait_for_email.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginWaitForEmailBinding +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.failure.is401 import javax.inject.Inject @@ -34,11 +38,13 @@ data class LoginWaitForEmailFragmentArgument( /** * In this screen, the user is asked to check his emails */ -class LoginWaitForEmailFragment @Inject constructor() : AbstractLoginFragment() { +class LoginWaitForEmailFragment @Inject constructor() : AbstractLoginFragment() { private val params: LoginWaitForEmailFragmentArgument by args() - override fun getLayoutResId() = R.layout.fragment_login_wait_for_email + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWaitForEmailBinding { + return FragmentLoginWaitForEmailBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -59,7 +65,7 @@ class LoginWaitForEmailFragment @Inject constructor() : AbstractLoginFragment() } private fun setupUi() { - loginWaitForEmailNotice.text = getString(R.string.login_wait_for_email_notice, params.email) + views.loginWaitForEmailNotice.text = getString(R.string.login_wait_for_email_notice, params.email) } override fun onError(throwable: Throwable) { diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index 78a24abfd3..eaa7471da2 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -24,7 +24,9 @@ import android.graphics.Bitmap import android.net.http.SslError import android.os.Bundle import android.view.KeyEvent +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.webkit.SslErrorHandler import android.webkit.WebView import android.webkit.WebViewClient @@ -33,9 +35,11 @@ import com.airbnb.mvrx.activityViewModel import im.vector.app.R import im.vector.app.core.extensions.appendParamToUrl import im.vector.app.core.utils.AssetReader +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel -import kotlinx.android.synthetic.main.fragment_login_web.* + import org.matrix.android.sdk.api.auth.LOGIN_FALLBACK_PATH import org.matrix.android.sdk.api.auth.REGISTER_FALLBACK_PATH import org.matrix.android.sdk.api.auth.data.Credentials @@ -50,9 +54,11 @@ import javax.inject.Inject */ class LoginWebFragment @Inject constructor( private val assetReader: AssetReader -) : AbstractLoginFragment() { +) : AbstractLoginFragment() { - override fun getLayoutResId() = R.layout.fragment_login_web + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginWebBinding { + return FragmentLoginWebBinding.inflate(inflater, container, false) + } private var isWebViewLoaded = false private var isForSessionRecovery = false @@ -60,7 +66,7 @@ class LoginWebFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setupToolbar(loginWebToolbar) + setupToolbar(views.loginWebToolbar) } override fun updateWithState(state: LoginViewState) { @@ -75,7 +81,7 @@ class LoginWebFragment @Inject constructor( } private fun setupTitle(state: LoginViewState) { - loginWebToolbar.title = when (state.signMode) { + views.loginWebToolbar.title = when (state.signMode) { SignMode.SignIn -> getString(R.string.login_signin) else -> getString(R.string.login_signup) } @@ -83,15 +89,15 @@ class LoginWebFragment @Inject constructor( @SuppressLint("SetJavaScriptEnabled") private fun setupWebView(state: LoginViewState) { - loginWebWebView.settings.javaScriptEnabled = true + views.loginWebWebView.settings.javaScriptEnabled = true // Enable local storage to support SSO with Firefox accounts - loginWebWebView.settings.domStorageEnabled = true - loginWebWebView.settings.databaseEnabled = true + views.loginWebWebView.settings.domStorageEnabled = true + views.loginWebWebView.settings.databaseEnabled = true // Due to https://developers.googleblog.com/2016/08/modernizing-oauth-interactions-in-native-apps.html, we hack // the user agent to bypass the limitation of Google, as a quick fix (a proper solution will be to use the SSO SDK) - loginWebWebView.settings.userAgentString = "Mozilla/5.0 Google" + views.loginWebWebView.settings.userAgentString = "Mozilla/5.0 Google" // AppRTC requires third party cookies to work val cookieManager = android.webkit.CookieManager.getInstance() @@ -128,9 +134,9 @@ class LoginWebFragment @Inject constructor( } } - loginWebWebView.loadUrl(url) + views.loginWebWebView.loadUrl(url) - loginWebWebView.webViewClient = object : WebViewClient() { + views.loginWebWebView.webViewClient = object : WebViewClient() { override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { AlertDialog.Builder(requireActivity()) @@ -158,7 +164,7 @@ class LoginWebFragment @Inject constructor( override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { super.onPageStarted(view, url, favicon) - loginWebToolbar.subtitle = url + views.loginWebToolbar.subtitle = url } override fun onPageFinished(view: WebView, url: String) { @@ -259,9 +265,9 @@ class LoginWebFragment @Inject constructor( override fun onBackPressed(toolbarButton: Boolean): Boolean { return when { - toolbarButton -> super.onBackPressed(toolbarButton) - loginWebWebView.canGoBack() -> loginWebWebView.goBack().run { true } - else -> super.onBackPressed(toolbarButton) + toolbarButton -> super.onBackPressed(toolbarButton) + views.loginWebWebView.canGoBack() -> views.loginWebWebView.goBack().run { true } + else -> super.onBackPressed(toolbarButton) } } } diff --git a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt index 8561b1035a..5ec523b9db 100755 --- a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt @@ -18,18 +18,22 @@ package im.vector.app.features.login.terms import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.args import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.toReducedUrl import im.vector.app.core.utils.openUrlInChromeCustomTab +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLoginTermsBinding import im.vector.app.features.login.AbstractLoginFragment import im.vector.app.features.login.LoginAction import im.vector.app.features.login.LoginViewState -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_login_terms.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms import javax.inject.Inject @@ -43,12 +47,14 @@ data class LoginTermsFragmentArgument( */ class LoginTermsFragment @Inject constructor( private val policyController: PolicyController -) : AbstractLoginFragment(), +) : AbstractLoginFragment(), PolicyController.PolicyControllerListener { private val params: LoginTermsFragmentArgument by args() - override fun getLayoutResId() = R.layout.fragment_login_terms + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginTermsBinding { + return FragmentLoginTermsBinding.inflate(inflater, container, false) + } private var loginTermsViewState: LoginTermsViewState = LoginTermsViewState(emptyList()) @@ -56,7 +62,7 @@ class LoginTermsFragment @Inject constructor( super.onViewCreated(view, savedInstanceState) setupViews() - loginTermsPolicyList.configureWith(policyController) + views.loginTermsPolicyList.configureWith(policyController) policyController.listener = this val list = ArrayList() @@ -70,11 +76,11 @@ class LoginTermsFragment @Inject constructor( } private fun setupViews() { - loginTermsSubmit.setOnClickListener { submit() } + views.loginTermsSubmit.setOnClickListener { submit() } } override fun onDestroyView() { - loginTermsPolicyList.cleanup() + views.loginTermsPolicyList.cleanup() policyController.listener = null super.onDestroyView() } @@ -83,7 +89,7 @@ class LoginTermsFragment @Inject constructor( policyController.setData(loginTermsViewState.localizedFlowDataLoginTermsChecked) // Button is enabled only if all checkboxes are checked - loginTermsSubmit.isEnabled = loginTermsViewState.allChecked() + views.loginTermsSubmit.isEnabled = loginTermsViewState.allChecked() } override fun setChecked(localizedFlowDataLoginTerms: LocalizedFlowDataLoginTerms, isChecked: Boolean) { diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt index 69f30bb470..1b0ccc66b5 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheet.kt @@ -18,7 +18,9 @@ package im.vector.app.features.matrixto import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isInvisible import androidx.core.view.isVisible import com.airbnb.mvrx.Fail @@ -32,12 +34,15 @@ import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetMatrixToCardBinding import im.vector.app.features.home.AvatarRenderer -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_matrix_to_card.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject -class MatrixToBottomSheet : VectorBaseBottomSheetDialogFragment() { +class MatrixToBottomSheet : + VectorBaseBottomSheetDialogFragment() { @Parcelize data class MatrixToArgs( @@ -55,7 +60,9 @@ class MatrixToBottomSheet : VectorBaseBottomSheetDialogFragment() { private var interactionListener: InteractionListener? = null - override fun getLayoutResId() = R.layout.bottom_sheet_matrix_to_card + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetMatrixToCardBinding { + return BottomSheetMatrixToCardBinding.inflate(inflater, container, false) + } private val viewModel by fragmentViewModel(MatrixToBottomSheetViewModel::class) @@ -67,19 +74,19 @@ class MatrixToBottomSheet : VectorBaseBottomSheetDialogFragment() { super.invalidate() when (val item = state.matrixItem) { Uninitialized -> { - matrixToCardContentLoading.isVisible = false - matrixToCardUserContentVisibility.isVisible = false + views.matrixToCardContentLoading.isVisible = false + views.matrixToCardUserContentVisibility.isVisible = false } is Loading -> { - matrixToCardContentLoading.isVisible = true - matrixToCardUserContentVisibility.isVisible = false + views.matrixToCardContentLoading.isVisible = true + views.matrixToCardUserContentVisibility.isVisible = false } is Success -> { - matrixToCardContentLoading.isVisible = false - matrixToCardUserContentVisibility.isVisible = true - matrixToCardNameText.setTextOrHide(item.invoke().displayName) - matrixToCardUserIdText.setTextOrHide(item.invoke().id) - avatarRenderer.render(item.invoke(), matrixToCardAvatar) + views.matrixToCardContentLoading.isVisible = false + views.matrixToCardUserContentVisibility.isVisible = true + views.matrixToCardNameText.setTextOrHide(item.invoke().displayName) + views.matrixToCardUserIdText.setTextOrHide(item.invoke().id) + avatarRenderer.render(item.invoke(), views.matrixToCardAvatar) } is Fail -> { // TODO display some error copy? @@ -89,29 +96,29 @@ class MatrixToBottomSheet : VectorBaseBottomSheetDialogFragment() { when (state.startChattingState) { Uninitialized -> { - matrixToCardButtonLoading.isVisible = false - matrixToCardSendMessageButton.isVisible = false + views.matrixToCardButtonLoading.isVisible = false + views.matrixToCardSendMessageButton.isVisible = false } is Success -> { - matrixToCardButtonLoading.isVisible = false - matrixToCardSendMessageButton.isVisible = true + views.matrixToCardButtonLoading.isVisible = false + views.matrixToCardSendMessageButton.isVisible = true } is Fail -> { - matrixToCardButtonLoading.isVisible = false - matrixToCardSendMessageButton.isVisible = true + views.matrixToCardButtonLoading.isVisible = false + views.matrixToCardSendMessageButton.isVisible = true // TODO display some error copy? dismiss() } is Loading -> { - matrixToCardButtonLoading.isVisible = true - matrixToCardSendMessageButton.isInvisible = true + views.matrixToCardButtonLoading.isVisible = true + views.matrixToCardSendMessageButton.isInvisible = true } } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - matrixToCardSendMessageButton.debouncedClicks { + views.matrixToCardSendMessageButton.debouncedClicks { withState(viewModel) { it.matrixItem.invoke()?.let { item -> viewModel.handle(MatrixToAction.StartChattingWithUser(item)) diff --git a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt index 195421ff58..3eff056ae9 100644 --- a/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/BigImageViewerActivity.kt @@ -19,29 +19,32 @@ package im.vector.app.features.media import android.content.Context import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import androidx.core.net.toUri import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.synthetic.main.activity_big_image_viewer.* +import im.vector.app.databinding.ActivityBigImageViewerBinding + import javax.inject.Inject /** * Simple Activity to display an avatar in fullscreen */ -class BigImageViewerActivity : VectorBaseActivity() { +class BigImageViewerActivity : VectorBaseActivity() { @Inject lateinit var sessionHolder: ActiveSessionHolder + override fun getBinding() = ActivityBigImageViewerBinding.inflate(layoutInflater) + override fun injectWith(injector: ScreenComponent) { injector.inject(this) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_big_image_viewer) - setSupportActionBar(bigImageViewerToolbar) + setSupportActionBar(views.bigImageViewerToolbar) supportActionBar?.apply { title = intent.getStringExtra(EXTRA_TITLE) setHomeButtonEnabled(true) @@ -56,7 +59,7 @@ class BigImageViewerActivity : VectorBaseActivity() { if (uri == null) { finish() } else { - bigImageViewerImageView.showImage(uri) + views.bigImageViewerImageView.showImage(uri) } } diff --git a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt index 4670c82db1..75c7912646 100644 --- a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt @@ -39,7 +39,7 @@ import im.vector.app.core.glide.GlideRequests import im.vector.app.core.ui.model.Size import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.isLocalFile -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt diff --git a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt index e7f4806e31..c632a008ce 100644 --- a/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/media/VectorAttachmentViewerActivity.kt @@ -42,7 +42,7 @@ import im.vector.app.features.themes.ActivityOtherThemes import im.vector.app.features.themes.ThemeUtils import im.vector.lib.attachmentviewer.AttachmentCommands import im.vector.lib.attachmentviewer.AttachmentViewerActivity -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import timber.log.Timber import javax.inject.Inject import kotlin.system.measureTimeMillis diff --git a/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt index d8eddc7331..c771eece8f 100644 --- a/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt @@ -25,7 +25,7 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.utils.isLocalFile -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt index e8064aaec5..02c9c7f717 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandlerActivity.kt @@ -23,16 +23,19 @@ import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.FragmentProgressBinding import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.LoadingFragment import im.vector.app.features.login.LoginActivity import javax.inject.Inject -class PermalinkHandlerActivity : VectorBaseActivity() { +class PermalinkHandlerActivity : VectorBaseActivity() { @Inject lateinit var permalinkHandler: PermalinkHandler @Inject lateinit var sessionHolder: ActiveSessionHolder + override fun getBinding() = FragmentProgressBinding.inflate(layoutInflater) + override fun injectWith(injector: ScreenComponent) { injector.inject(this) } diff --git a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt index 2e6a0b6c08..4828895ec1 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinActivity.kt @@ -24,8 +24,9 @@ import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding -class PinActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { +class PinActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity { companion object { fun newIntent(context: Context, args: PinArgs): Intent { @@ -35,7 +36,7 @@ class PinActivity : VectorBaseActivity(), ToolbarConfigurable, UnlockedActivity } } - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() =ActivitySimpleBinding.inflate(layoutInflater) override fun initUiAndData() { if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt index 1aa4846f38..8dcb1689c7 100644 --- a/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt +++ b/vector/src/main/java/im/vector/app/features/pin/PinFragment.kt @@ -19,7 +19,9 @@ package im.vector.app.features.pin import android.app.Activity import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.app.AlertDialog import androidx.lifecycle.lifecycleScope @@ -30,10 +32,12 @@ import im.vector.app.R import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.toast +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentPinBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.settings.VectorPreferences -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import kotlinx.coroutines.launch import javax.inject.Inject @@ -45,11 +49,13 @@ data class PinArgs( class PinFragment @Inject constructor( private val pinCodeStore: PinCodeStore, private val vectorPreferences: VectorPreferences -) : VectorBaseFragment() { +) : VectorBaseFragment() { private val fragmentArgs: PinArgs by args() - override fun getLayoutResId() = R.layout.fragment_pin + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentPinBinding { + return FragmentPinBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt index 8a5126a160..fc30c2808b 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerActivity.kt @@ -27,10 +27,11 @@ import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding -class QrCodeScannerActivity : VectorBaseActivity() { +class QrCodeScannerActivity : VectorBaseActivity() { - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt index 6371e3c29b..af3ffdaa94 100644 --- a/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/qrcode/QrCodeScannerFragment.kt @@ -16,31 +16,37 @@ package im.vector.app.features.qrcode +import android.view.LayoutInflater +import android.view.ViewGroup import com.google.zxing.Result import im.vector.app.R import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_qr_code_scanner.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentQrCodeScannerBinding + import me.dm7.barcodescanner.zxing.ZXingScannerView import javax.inject.Inject class QrCodeScannerFragment @Inject constructor() - : VectorBaseFragment(), + : VectorBaseFragment(), ZXingScannerView.ResultHandler { - override fun getLayoutResId() = R.layout.fragment_qr_code_scanner + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerBinding { + return FragmentQrCodeScannerBinding.inflate(inflater, container, false) + } override fun onResume() { super.onResume() // Register ourselves as a handler for scan results. - scannerView.setResultHandler(this) + views.scannerView.setResultHandler(this) // Start camera on resume - scannerView.startCamera() + views.scannerView.startCamera() } override fun onPause() { super.onPause() // Stop camera on pause - scannerView.stopCamera() + views.scannerView.stopCamera() } override fun handleResult(rawResult: Result?) { diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt index 830f49f92f..38ff9ce5ae 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReportActivity.kt @@ -16,6 +16,7 @@ package im.vector.app.features.rageshake +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.widget.Toast @@ -24,32 +25,33 @@ import androidx.core.widget.doOnTextChanged import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.synthetic.main.activity_bug_report.* +import im.vector.app.databinding.ActivityBugReportBinding + import timber.log.Timber /** * Form to send a bug report */ -class BugReportActivity : VectorBaseActivity() { +class BugReportActivity : VectorBaseActivity() { override fun injectWith(injector: ScreenComponent) { injector.inject(this) } - override fun getLayoutRes() = R.layout.activity_bug_report + override fun getBinding() = ActivityBugReportBinding.inflate(layoutInflater) private var forSuggestion: Boolean = false override fun initUiAndData() { - configureToolbar(bugReportToolbar) + configureToolbar(views.bugReportToolbar) setupViews() if (bugReporter.screenshot != null) { - bug_report_screenshot_preview.setImageBitmap(bugReporter.screenshot) + views.bugReportScreenshotPreview.setImageBitmap(bugReporter.screenshot) } else { - bug_report_screenshot_preview.isVisible = false - bug_report_button_include_screenshot.isChecked = false - bug_report_button_include_screenshot.isEnabled = false + views.bugReportScreenshotPreview.isVisible = false + views.bugReportButtonIncludeScreenshot.isChecked = false + views.bugReportButtonIncludeScreenshot.isEnabled = false } forSuggestion = intent.getBooleanExtra("FOR_SUGGESTION", false) @@ -58,19 +60,19 @@ class BugReportActivity : VectorBaseActivity() { if (forSuggestion) { supportActionBar?.setTitle(R.string.send_suggestion) - bug_report_first_text.setText(R.string.send_suggestion_content) - bug_report_text_input_layout.hint = getString(R.string.send_suggestion_report_placeholder) + views.bugReportFirstText.setText(R.string.send_suggestion_content) + views.bugReportTextInputLayout.hint = getString(R.string.send_suggestion_report_placeholder) - bug_report_logs_description.isVisible = false + views.bugReportLogsDescription.isVisible = false - bug_report_button_include_logs.isChecked = false - bug_report_button_include_logs.isVisible = false + views.bugReportButtonIncludeLogs.isChecked = false + views.bugReportButtonIncludeLogs.isVisible = false - bug_report_button_include_crash_logs.isChecked = false - bug_report_button_include_crash_logs.isVisible = false + views.bugReportButtonIncludeCrashLogs.isChecked = false + views.bugReportButtonIncludeCrashLogs.isVisible = false - bug_report_button_include_key_share_history.isChecked = false - bug_report_button_include_key_share_history.isVisible = false + views.bugReportButtonIncludeKeyShareHistory.isChecked = false + views.bugReportButtonIncludeKeyShareHistory.isVisible = false // Keep the screenshot } else { @@ -79,15 +81,15 @@ class BugReportActivity : VectorBaseActivity() { } private fun setupViews() { - bug_report_edit_text.doOnTextChanged { _, _, _, _ -> textChanged() } - bug_report_button_include_screenshot.setOnCheckedChangeListener { _, _ -> onSendScreenshotChanged() } + views.bugReportEditText.doOnTextChanged { _, _, _, _ -> textChanged() } + views.bugReportButtonIncludeScreenshot.setOnCheckedChangeListener { _, _ -> onSendScreenshotChanged() } } override fun getMenuRes() = R.menu.bug_report override fun onPrepareOptionsMenu(menu: Menu): Boolean { menu.findItem(R.id.ic_action_send_bug_report)?.let { - val isValid = !bug_report_mask_view.isVisible + val isValid = !views.bugReportMaskView.isVisible it.isEnabled = isValid it.icon.alpha = if (isValid) 255 else 100 @@ -99,10 +101,10 @@ class BugReportActivity : VectorBaseActivity() { override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.ic_action_send_bug_report -> { - if (bug_report_edit_text.text.toString().trim().length >= 10) { + if (views.bugReportEditText.text.toString().trim().length >= 10) { sendBugReport() } else { - bug_report_text_input_layout.error = getString(R.string.bug_report_error_too_short) + views.bugReportTextInputLayout.error = getString(R.string.bug_report_error_too_short) } return true } @@ -114,24 +116,24 @@ class BugReportActivity : VectorBaseActivity() { * Send the bug report */ private fun sendBugReport() { - bug_report_scrollview.alpha = 0.3f - bug_report_mask_view.isVisible = true + views.bugReportScrollview.alpha = 0.3f + views.bugReportMaskView.isVisible = true invalidateOptionsMenu() - bug_report_progress_text_view.isVisible = true - bug_report_progress_text_view.text = getString(R.string.send_bug_report_progress, "0") + views.bugReportProgressTextView.isVisible = true + views.bugReportProgressTextView.text = getString(R.string.send_bug_report_progress, "0") - bug_report_progress_view.isVisible = true - bug_report_progress_view.progress = 0 + views.bugReportProgressView.isVisible = true + views.bugReportProgressView.progress = 0 bugReporter.sendBugReport(this, forSuggestion, - bug_report_button_include_logs.isChecked, - bug_report_button_include_crash_logs.isChecked, - bug_report_button_include_key_share_history.isChecked, - bug_report_button_include_screenshot.isChecked, - bug_report_edit_text.text.toString(), + views.bugReportButtonIncludeLogs.isChecked, + views.bugReportButtonIncludeCrashLogs.isChecked, + views.bugReportButtonIncludeKeyShareHistory.isChecked, + views.bugReportButtonIncludeScreenshot.isChecked, + views.bugReportEditText.text.toString(), object : BugReporter.IMXBugReportListener { override fun onUploadFailed(reason: String?) { try { @@ -148,10 +150,10 @@ class BugReportActivity : VectorBaseActivity() { Timber.e(e, "## onUploadFailed() : failed to display the toast") } - bug_report_mask_view.isVisible = false - bug_report_progress_view.isVisible = false - bug_report_progress_text_view.isVisible = false - bug_report_scrollview.alpha = 1.0f + views.bugReportMaskView.isVisible = false + views.bugReportProgressView.isVisible = false + views.bugReportProgressTextView.isVisible = false + views.bugReportScrollview.alpha = 1.0f invalidateOptionsMenu() } @@ -163,8 +165,8 @@ class BugReportActivity : VectorBaseActivity() { override fun onProgress(progress: Int) { val myProgress = progress.coerceIn(0, 100) - bug_report_progress_view.progress = myProgress - bug_report_progress_text_view.text = getString(R.string.send_bug_report_progress, myProgress.toString()) + views.bugReportProgressView.progress = myProgress + views.bugReportProgressTextView.text = getString(R.string.send_bug_report_progress, myProgress.toString()) } override fun onUploadSucceed() { @@ -192,11 +194,11 @@ class BugReportActivity : VectorBaseActivity() { * ========================================================================================== */ private fun textChanged() { - bug_report_text_input_layout.error = null + views.bugReportTextInputLayout.error = null } - internal fun onSendScreenshotChanged() { - bug_report_screenshot_preview.isVisible = bug_report_button_include_screenshot.isChecked && bugReporter.screenshot != null + private fun onSendScreenshotChanged() { + views.bugReportScreenshotPreview.isVisible = views.bugReportButtonIncludeScreenshot.isChecked && bugReporter.screenshot != null } override fun onBackPressed() { diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt index af40aa970d..588c1789f1 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiChooserFragment.kt @@ -16,20 +16,26 @@ package im.vector.app.features.reactions import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.emoji_chooser_fragment.* +import im.vector.app.databinding.EmojiChooserFragmentBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject class EmojiChooserFragment @Inject constructor( private val emojiRecyclerAdapter: EmojiRecyclerAdapter -) : VectorBaseFragment(), +) : VectorBaseFragment(), EmojiRecyclerAdapter.InteractionListener, ReactionClickListener { - override fun getLayoutResId() = R.layout.emoji_chooser_fragment + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): EmojiChooserFragmentBinding { + return EmojiChooserFragmentBinding.inflate(inflater, container, false) + } private lateinit var viewModel: EmojiChooserViewModel @@ -40,7 +46,7 @@ class EmojiChooserFragment @Inject constructor( emojiRecyclerAdapter.reactionClickListener = this emojiRecyclerAdapter.interactionListener = this - emojiRecyclerView.adapter = emojiRecyclerAdapter + views.emojiRecyclerView.adapter = emojiRecyclerAdapter viewModel.moveToSection.observe(viewLifecycleOwner) { section -> emojiRecyclerAdapter.scrollToSection(section) @@ -56,7 +62,7 @@ class EmojiChooserFragment @Inject constructor( } override fun onDestroyView() { - emojiRecyclerView.cleanup() + views.emojiRecyclerView.cleanup() emojiRecyclerAdapter.reactionClickListener = null emojiRecyclerAdapter.interactionListener = null super.onDestroyView() diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt index 25cb90d3a4..1efef67d07 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiReactionPickerActivity.kt @@ -35,9 +35,10 @@ import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.observeEvent import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityEmojiReactionPickerBinding import im.vector.app.features.reactions.data.EmojiDataSource import io.reactivex.android.schedulers.AndroidSchedulers -import kotlinx.android.synthetic.main.activity_emoji_reaction_picker.* + import timber.log.Timber import java.util.concurrent.TimeUnit import javax.inject.Inject @@ -47,7 +48,7 @@ import javax.inject.Inject * TODO: Loading indicator while getting emoji data source? * TODO: Finish Refactor to vector base activity */ -class EmojiReactionPickerActivity : VectorBaseActivity(), +class EmojiReactionPickerActivity : VectorBaseActivity(), EmojiCompatFontProvider.FontProviderListener { private lateinit var tabLayout: TabLayout @@ -56,7 +57,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), override fun getMenuRes() = R.menu.menu_emoji_reaction_picker - override fun getLayoutRes() = R.layout.activity_emoji_reaction_picker + override fun getBinding() = ActivityEmojiReactionPickerBinding.inflate(layoutInflater) override fun getTitleRes() = R.string.title_activity_emoji_reaction_picker @@ -83,7 +84,7 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), } override fun initUiAndData() { - configureToolbar(emojiPickerToolbar) + configureToolbar(views.emojiPickerToolbar) emojiCompatFontProvider.let { EmojiDrawView.configureTextPaint(this, it.typeface) it.addListener(this) @@ -127,8 +128,8 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), } } - emojiPickerWholeListFragmentContainer.isVisible = true - emojiPickerFilteredListFragmentContainer.isVisible = false + views.emojiPickerWholeListFragmentContainer.isVisible = true + views.emojiPickerFilteredListFragmentContainer.isVisible = false tabLayout.isVisible = true } @@ -191,12 +192,12 @@ class EmojiReactionPickerActivity : VectorBaseActivity(), private fun onQueryText(query: String) { if (query.isEmpty()) { tabLayout.isVisible = true - emojiPickerWholeListFragmentContainer.isVisible = true - emojiPickerFilteredListFragmentContainer.isVisible = false + views.emojiPickerWholeListFragmentContainer.isVisible = true + views.emojiPickerFilteredListFragmentContainer.isVisible = false } else { tabLayout.isVisible = false - emojiPickerWholeListFragmentContainer.isVisible = false - emojiPickerFilteredListFragmentContainer.isVisible = true + views.emojiPickerWholeListFragmentContainer.isVisible = false + views.emojiPickerFilteredListFragmentContainer.isVisible = true searchResultViewModel.handle(EmojiSearchAction.UpdateQuery(query)) } } diff --git a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultFragment.kt b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultFragment.kt index 28df628cf1..435d19013e 100644 --- a/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultFragment.kt +++ b/vector/src/main/java/im/vector/app/features/reactions/EmojiSearchResultFragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.reactions import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -24,14 +26,17 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.LiveEvent -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject class EmojiSearchResultFragment @Inject constructor( private val epoxyController: EmojiSearchResultController -) : VectorBaseFragment(), ReactionClickListener { +) : VectorBaseFragment(), ReactionClickListener { - 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: EmojiSearchResultViewModel by activityViewModel() @@ -41,12 +46,12 @@ class EmojiSearchResultFragment @Inject constructor( super.onViewCreated(view, savedInstanceState) sharedViewModel = activityViewModelProvider.get(EmojiChooserViewModel::class.java) epoxyController.listener = this - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) } override fun onDestroyView() { epoxyController.listener = null - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt index b180018480..44477a2b5b 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt @@ -17,8 +17,10 @@ package im.vector.app.features.roomdirectory import android.os.Bundle +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import com.google.android.material.snackbar.Snackbar @@ -30,10 +32,12 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.toast +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentPublicRoomsBinding import im.vector.app.features.permalink.NavigationInterceptor import im.vector.app.features.permalink.PermalinkHandler import io.reactivex.rxkotlin.subscribeBy -import kotlinx.android.synthetic.main.fragment_public_rooms.* + import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import timber.log.Timber @@ -48,19 +52,22 @@ class PublicRoomsFragment @Inject constructor( private val publicRoomsController: PublicRoomsController, private val permalinkHandler: PermalinkHandler, private val session: Session -) : VectorBaseFragment(), PublicRoomsController.Callback { +) : VectorBaseFragment(), + PublicRoomsController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel - override fun getLayoutResId() = R.layout.fragment_public_rooms + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentPublicRoomsBinding { + return FragmentPublicRoomsBinding.inflate(inflater, container, false) + } override fun getMenuRes() = R.menu.menu_room_directory override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - vectorBaseActivity.setSupportActionBar(publicRoomsToolbar) + vectorBaseActivity.setSupportActionBar(views.publicRoomsToolbar) vectorBaseActivity.supportActionBar?.let { it.setDisplayShowHomeEnabled(true) @@ -70,14 +77,14 @@ class PublicRoomsFragment @Inject constructor( sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupRecyclerView() - publicRoomsFilter.queryTextChanges() + views.publicRoomsFilter.queryTextChanges() .debounce(500, TimeUnit.MILLISECONDS) .subscribeBy { viewModel.handle(RoomDirectoryAction.FilterWith(it.toString())) } .disposeOnDestroyView() - publicRoomsCreateNewRoom.debouncedClicks { + views.publicRoomsCreateNewRoom.debouncedClicks { sharedActionViewModel.post(RoomDirectorySharedAction.CreateRoom) } @@ -89,7 +96,7 @@ class PublicRoomsFragment @Inject constructor( private fun handleViewEvents(viewEvents: RoomDirectoryViewEvents) { when (viewEvents) { is RoomDirectoryViewEvents.Failure -> { - Snackbar.make(publicRoomsCoordinator, errorFormatter.toHumanReadable(viewEvents.throwable), Snackbar.LENGTH_SHORT) + Snackbar.make(views.publicRoomsCoordinator, errorFormatter.toHumanReadable(viewEvents.throwable), Snackbar.LENGTH_SHORT) .show() } }.exhaustive @@ -97,7 +104,7 @@ class PublicRoomsFragment @Inject constructor( override fun onDestroyView() { publicRoomsController.callback = null - publicRoomsList.cleanup() + views.publicRoomsList.cleanup() super.onDestroyView() } @@ -113,8 +120,8 @@ class PublicRoomsFragment @Inject constructor( } private fun setupRecyclerView() { - publicRoomsList.trackItemsVisibilityChange() - publicRoomsList.configureWith(publicRoomsController) + views.publicRoomsList.trackItemsVisibilityChange() + views.publicRoomsList.configureWith(publicRoomsController) publicRoomsController.callback = this } @@ -164,9 +171,9 @@ class PublicRoomsFragment @Inject constructor( override fun invalidate() = withState(viewModel) { state -> if (!initialValueSet) { initialValueSet = true - if (publicRoomsFilter.query.toString() != state.currentFilter) { + if (views.publicRoomsFilter.query.toString() != state.currentFilter) { // For initial filter - publicRoomsFilter.setQuery(state.currentFilter, false) + views.publicRoomsFilter.setQuery(state.currentFilter, false) } } diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt index a21f4e670a..833be9164e 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/RoomDirectoryActivity.kt @@ -26,18 +26,19 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.roomdirectory.createroom.CreateRoomFragment import im.vector.app.features.roomdirectory.createroom.CreateRoomArgs import im.vector.app.features.roomdirectory.picker.RoomDirectoryPickerFragment import javax.inject.Inject -class RoomDirectoryActivity : VectorBaseActivity() { +class RoomDirectoryActivity : VectorBaseActivity() { @Inject lateinit var roomDirectoryViewModelFactory: RoomDirectoryViewModel.Factory private val roomDirectoryViewModel: RoomDirectoryViewModel by viewModel() private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { injector.inject(this) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt index b6ee00a52f..58058c3a02 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomActivity.kt @@ -25,17 +25,18 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel /** * Simple container for [CreateRoomFragment] */ -class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { +class CreateRoomActivity : VectorBaseActivity(), ToolbarConfigurable { private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun configure(toolbar: Toolbar) { configureToolbar(toolbar) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt index f859009b13..73dc94fb0d 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/createroom/CreateRoomFragment.kt @@ -19,7 +19,9 @@ package im.vector.app.features.roomdirectory.createroom import android.net.Uri import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import com.airbnb.mvrx.Loading @@ -35,11 +37,13 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider +import im.vector.app.databinding.FragmentCreateRoomBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_create_room.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import kotlinx.parcelize.Parcelize + + import org.matrix.android.sdk.api.session.room.failure.CreateRoomFailure import javax.inject.Inject @@ -52,7 +56,7 @@ class CreateRoomFragment @Inject constructor( private val createRoomController: CreateRoomController, val createRoomViewModelFactory: CreateRoomViewModel.Factory, colorProvider: ColorProvider -) : VectorBaseFragment(), +) : VectorBaseFragment(), CreateRoomController.Listener, GalleryOrCameraDialogHelper.Listener, OnBackPressed { @@ -63,15 +67,17 @@ class CreateRoomFragment @Inject constructor( private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this, colorProvider) - override fun getLayoutResId() = R.layout.fragment_create_room + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentCreateRoomBinding { + return FragmentCreateRoomBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - vectorBaseActivity.setSupportActionBar(createRoomToolbar) + vectorBaseActivity.setSupportActionBar(views.createRoomToolbar) sharedActionViewModel = activityViewModelProvider.get(RoomDirectorySharedActionViewModel::class.java) setupWaitingView() setupRecyclerView() - createRoomClose.debouncedClicks { + views.createRoomClose.debouncedClicks { sharedActionViewModel.post(RoomDirectorySharedAction.Back) } viewModel.observeViewEvents { @@ -90,18 +96,18 @@ class CreateRoomFragment @Inject constructor( } private fun setupWaitingView() { - waitingStatusText.isVisible = true - waitingStatusText.setText(R.string.create_room_in_progress) + views.waitingView.waitingStatusText.isVisible = true + views.waitingView.waitingStatusText.setText(R.string.create_room_in_progress) } override fun onDestroyView() { - createRoomForm.cleanup() + views.createRoomForm.cleanup() createRoomController.listener = null super.onDestroyView() } private fun setupRecyclerView() { - createRoomForm.configureWith(createRoomController) + views.createRoomForm.configureWith(createRoomController) createRoomController.listener = this } @@ -169,7 +175,7 @@ class CreateRoomFragment @Inject constructor( override fun invalidate() = withState(viewModel) { state -> val async = state.asyncCreateRoomRequest - waiting_view.isVisible = async is Loading + views.waitingView.root.isVisible = async is Loading if (async is Success) { // Navigate to freshly created room navigator.openRoom(requireActivity(), async()) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt index 4bfd60394a..d863541b23 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/picker/RoomDirectoryPickerFragment.kt @@ -17,8 +17,11 @@ package im.vector.app.features.roomdirectory.picker import android.os.Bundle +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -27,11 +30,13 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomDirectoryPickerBinding import im.vector.app.features.roomdirectory.RoomDirectoryAction import im.vector.app.features.roomdirectory.RoomDirectorySharedAction import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel import im.vector.app.features.roomdirectory.RoomDirectoryViewModel -import kotlinx.android.synthetic.main.fragment_room_directory_picker.* + import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import timber.log.Timber import javax.inject.Inject @@ -39,18 +44,21 @@ import javax.inject.Inject // TODO Menu to add custom room directory (not done in RiotWeb so far...) class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerViewModelFactory: RoomDirectoryPickerViewModel.Factory, private val roomDirectoryPickerController: RoomDirectoryPickerController -) : VectorBaseFragment(), RoomDirectoryPickerController.Callback { +) : VectorBaseFragment(), + RoomDirectoryPickerController.Callback { private val viewModel: RoomDirectoryViewModel by activityViewModel() private lateinit var sharedActionViewModel: RoomDirectorySharedActionViewModel private val pickerViewModel: RoomDirectoryPickerViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_room_directory_picker + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomDirectoryPickerBinding { + return FragmentRoomDirectoryPickerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - vectorBaseActivity.setSupportActionBar(toolbar) + vectorBaseActivity.setSupportActionBar(views.toolbar) vectorBaseActivity.supportActionBar?.let { it.setDisplayShowHomeEnabled(true) @@ -62,7 +70,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie } override fun onDestroyView() { - roomDirectoryPickerList.cleanup() + views.roomDirectoryPickerList.cleanup() roomDirectoryPickerController.callback = null super.onDestroyView() } @@ -80,7 +88,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie } private fun setupRecyclerView() { - roomDirectoryPickerList.configureWith(roomDirectoryPickerController) + views.roomDirectoryPickerList.configureWith(roomDirectoryPickerController) roomDirectoryPickerController.callback = this } @@ -93,7 +101,7 @@ class RoomDirectoryPickerFragment @Inject constructor(val roomDirectoryPickerVie override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.select_room_directory) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.select_room_directory) } override fun retry() { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt index 3585c8bbf2..d0d617469c 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewActivity.kt @@ -24,7 +24,8 @@ import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.parcel.Parcelize +import im.vector.app.databinding.ActivitySimpleBinding +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoom import org.matrix.android.sdk.api.session.room.model.thirdparty.RoomDirectoryData import org.matrix.android.sdk.api.util.MatrixItem @@ -47,7 +48,7 @@ data class RoomPreviewData( get() = MatrixItem.RoomItem(roomId, roomName ?: roomAlias, avatarUrl) } -class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { +class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { private const val ARG = "ARG" @@ -72,7 +73,7 @@ class RoomPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { } } - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun configure(toolbar: Toolbar) { configureToolbar(toolbar) diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt index bc4552fc11..577b39ca19 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/roompreview/RoomPreviewNoPreviewFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roomdirectory.roompreview import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import androidx.transition.TransitionManager import com.airbnb.mvrx.Loading @@ -29,9 +31,11 @@ import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.ButtonStateView import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomPreviewNoPreviewBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomdirectory.JoinState -import kotlinx.android.synthetic.main.fragment_room_preview_no_preview.* + import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject @@ -41,12 +45,14 @@ import javax.inject.Inject class RoomPreviewNoPreviewFragment @Inject constructor( val roomPreviewViewModelFactory: RoomPreviewViewModel.Factory, private val avatarRenderer: AvatarRenderer -) : VectorBaseFragment() { +) : VectorBaseFragment() { private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel() private val roomPreviewData: RoomPreviewData by args() - override fun getLayoutResId() = R.layout.fragment_room_preview_no_preview + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPreviewNoPreviewBinding { + return FragmentRoomPreviewNoPreviewBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index e994a3c3ec..29a8fb31cd 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -19,8 +19,10 @@ package im.vector.app.features.roommemberprofile import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import com.airbnb.mvrx.Fail @@ -41,15 +43,17 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.startSharePlainTextIntent +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailPendingAction import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_matrix_profile.* -import kotlinx.android.synthetic.main.view_stub_room_member_profile_header.* +import kotlinx.parcelize.Parcelize + + import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject @@ -65,14 +69,17 @@ class RoomMemberProfileFragment @Inject constructor( private val roomMemberProfileController: RoomMemberProfileController, private val avatarRenderer: AvatarRenderer, private val roomDetailPendingActionStore: RoomDetailPendingActionStore -) : VectorBaseFragment(), RoomMemberProfileController.Callback { +) : VectorBaseFragment(), + RoomMemberProfileController.Callback { private val fragmentArgs: RoomMemberProfileArgs by args() private val viewModel: RoomMemberProfileViewModel by fragmentViewModel() private var appBarStateChangeListener: AppBarStateChangeListener? = null - override fun getLayoutResId() = R.layout.fragment_matrix_profile + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMatrixProfileBinding { + return FragmentMatrixProfileBinding.inflate(inflater, container, false) + } override fun getMenuRes() = R.menu.vector_room_member_profile diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt index 323e25a022..191a30724f 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheet.kt @@ -20,7 +20,9 @@ import android.content.DialogInterface import android.os.Bundle import android.os.Parcelable import android.view.KeyEvent +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.fragment.app.Fragment import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.fragmentViewModel @@ -30,14 +32,19 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetWithFragmentsBinding import im.vector.app.features.crypto.verification.VerificationBottomSheet -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import javax.inject.Inject import kotlin.reflect.KClass -class DeviceListBottomSheet : VectorBaseBottomSheetDialogFragment() { +class DeviceListBottomSheet : + VectorBaseBottomSheetDialogFragment() { - override fun getLayoutResId() = R.layout.bottom_sheet_with_fragments + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetWithFragmentsBinding { + return BottomSheetWithFragmentsBinding.inflate(inflater, container, false) + } private val viewModel: DeviceListBottomSheetViewModel by fragmentViewModel(DeviceListBottomSheetViewModel::class) diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt index 342213fac0..608d3cd209 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roommemberprofile.devices import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -25,23 +27,28 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceListFragment @Inject constructor( val dimensionConverter: DimensionConverter, val epoxyController: DeviceListEpoxyController -) : VectorBaseFragment(), DeviceListEpoxyController.InteractionListener { +) : VectorBaseFragment(), + DeviceListEpoxyController.InteractionListener { - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } private val viewModel: DeviceListBottomSheetViewModel by parentFragmentViewModel(DeviceListBottomSheetViewModel::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.setPadding(0, dimensionConverter.dpToPx(16), 0, dimensionConverter.dpToPx(16)) - bottomSheetRecyclerView.configureWith( + views.bottomSheetRecyclerView.setPadding(0, dimensionConverter.dpToPx(16), 0, dimensionConverter.dpToPx(16)) + views.bottomSheetRecyclerView.configureWith( epoxyController, showDivider = false, hasFixedSize = false) @@ -49,7 +56,7 @@ class DeviceListFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt index 1b5e571519..b153645976 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roommemberprofile.devices import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.parentFragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -25,23 +27,28 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceTrustInfoActionFragment @Inject constructor( val dimensionConverter: DimensionConverter, val epoxyController: DeviceTrustInfoEpoxyController -) : VectorBaseFragment(), DeviceTrustInfoEpoxyController.InteractionListener { +) : VectorBaseFragment(), + DeviceTrustInfoEpoxyController.InteractionListener { - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } private val viewModel: DeviceListBottomSheetViewModel by parentFragmentViewModel(DeviceListBottomSheetViewModel::class) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.setPadding(0, dimensionConverter.dpToPx(16), 0, dimensionConverter.dpToPx(16)) - bottomSheetRecyclerView.configureWith( + views.bottomSheetRecyclerView.setPadding(0, dimensionConverter.dpToPx(16), 0, dimensionConverter.dpToPx(16)) + views.bottomSheetRecyclerView.configureWith( epoxyController, showDivider = false, hasFixedSize = false) @@ -49,7 +56,7 @@ class DeviceTrustInfoActionFragment @Inject constructor( } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt index eee0cc4081..b0dbdacd49 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/powerlevel/EditPowerLevelDialogs.kt @@ -23,7 +23,7 @@ import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard -import kotlinx.android.synthetic.main.dialog_edit_power_level.view.* + import org.matrix.android.sdk.api.session.room.powerlevels.Role object EditPowerLevelDialogs { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 628e3869b4..2199cb7211 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -19,8 +19,10 @@ package im.vector.app.features.roomprofile import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.app.ActivityOptionsCompat import androidx.core.content.pm.ShortcutManagerCompat @@ -40,6 +42,8 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.copyToClipboard import im.vector.app.core.utils.startSharePlainTextIntent +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.features.crypto.util.toImageRes import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.list.actions.RoomListActionsArgs @@ -47,10 +51,10 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomS import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel import im.vector.app.features.media.BigImageViewerActivity -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_matrix_profile.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* -import kotlinx.android.synthetic.main.view_stub_room_profile_header.* +import kotlinx.parcelize.Parcelize + + + import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem @@ -66,7 +70,7 @@ class RoomProfileFragment @Inject constructor( private val roomProfileController: RoomProfileController, private val avatarRenderer: AvatarRenderer, val roomProfileViewModelFactory: RoomProfileViewModel.Factory -) : VectorBaseFragment(), +) : VectorBaseFragment(), RoomProfileController.Callback { private val roomProfileArgs: RoomProfileArgs by args() @@ -76,7 +80,9 @@ class RoomProfileFragment @Inject constructor( private var appBarStateChangeListener: AppBarStateChangeListener? = null - override fun getLayoutResId() = R.layout.fragment_matrix_profile + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMatrixProfileBinding { + return FragmentMatrixProfileBinding.inflate(inflater, container, false) + } override fun getMenuRes() = R.menu.vector_room_profile diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt index 689b057385..0edc985ebe 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/RoomAliasFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.roomprofile.alias import android.content.DialogInterface import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import com.airbnb.mvrx.args @@ -32,13 +34,15 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.shareText import im.vector.app.core.utils.toast +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheet import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedAction import im.vector.app.features.roomprofile.alias.detail.RoomAliasBottomSheetSharedActionViewModel -import kotlinx.android.synthetic.main.fragment_room_setting_generic.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* + + import org.matrix.android.sdk.api.session.room.alias.RoomAliasError import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.util.toMatrixItem @@ -49,7 +53,7 @@ class RoomAliasFragment @Inject constructor( private val controller: RoomAliasController, private val avatarRenderer: AvatarRenderer ) : - VectorBaseFragment(), + VectorBaseFragment(), RoomAliasController.Callback { private val viewModel: RoomAliasViewModel by fragmentViewModel() @@ -57,17 +61,19 @@ class RoomAliasFragment @Inject constructor( private val roomProfileArgs: RoomProfileArgs by args() - override fun getLayoutResId() = R.layout.fragment_room_setting_generic + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomSettingGenericBinding { + return FragmentRoomSettingGenericBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java) controller.callback = this - setupToolbar(roomSettingsToolbar) - roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true) - waitingStatusText.setText(R.string.please_wait) - waitingStatusText.isVisible = true + setupToolbar(views.roomSettingsToolbar) + views.roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true) + views.waitingView.waitingStatusText.setText(R.string.please_wait) + views.waitingView.waitingStatusText.isVisible = true viewModel.observeViewEvents { when (it) { @@ -110,20 +116,20 @@ class RoomAliasFragment @Inject constructor( override fun onDestroyView() { controller.callback = null - roomSettingsRecyclerView.cleanup() + views.roomSettingsRecyclerView.cleanup() super.onDestroyView() } override fun invalidate() = withState(viewModel) { state -> - waiting_view.isVisible = state.isLoading + views.waitingView.root.isVisible = state.isLoading controller.setData(state) renderRoomSummary(state) } private fun renderRoomSummary(state: RoomAliasViewState) { state.roomSummary()?.let { - roomSettingsToolbarTitleView.text = it.displayName - avatarRenderer.render(it.toMatrixItem(), roomSettingsToolbarAvatarImageView) + views.roomSettingsToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), views.roomSettingsToolbarAvatarImageView) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt index 265abe5862..6e6af86e66 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/alias/detail/RoomAliasBottomSheet.kt @@ -18,7 +18,9 @@ package im.vector.app.features.roomprofile.alias.detail import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState @@ -27,8 +29,9 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_generic_list.* +import im.vector.app.databinding.BottomSheetGenericListBinding +import kotlinx.parcelize.Parcelize + import javax.inject.Inject @Parcelize @@ -43,7 +46,9 @@ data class RoomAliasBottomSheetArgs( /** * Bottom sheet fragment that shows room alias information with list of contextual actions */ -class RoomAliasBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomAliasBottomSheetController.Listener { +class RoomAliasBottomSheet : + VectorBaseBottomSheetDialogFragment(), + RoomAliasBottomSheetController.Listener { private lateinit var sharedActionViewModel: RoomAliasBottomSheetSharedActionViewModel @Inject lateinit var sharedViewPool: RecyclerView.RecycledViewPool @@ -58,17 +63,19 @@ class RoomAliasBottomSheet : VectorBaseBottomSheetDialogFragment(), RoomAliasBot injector.inject(this) } - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListBinding { + return BottomSheetGenericListBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(RoomAliasBottomSheetSharedActionViewModel::class.java) - bottomSheetRecyclerView.configureWith(controller, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) + views.bottomSheetRecyclerView.configureWith(controller, viewPool = sharedViewPool, hasFixedSize = false, disableItemAnimation = true) controller.listener = this } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() controller.listener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt index 349321c87a..556d950230 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/banned/RoomBannedMemberListFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roomprofile.banned import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView import androidx.core.view.isVisible @@ -29,9 +31,10 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.toast +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs -import kotlinx.android.synthetic.main.fragment_room_setting_generic.* + import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -40,12 +43,15 @@ class RoomBannedMemberListFragment @Inject constructor( val viewModelFactory: RoomBannedMemberListViewModel.Factory, private val roomMemberListController: RoomBannedMemberListController, private val avatarRenderer: AvatarRenderer -) : VectorBaseFragment(), RoomBannedMemberListController.Callback { +) : VectorBaseFragment(), + RoomBannedMemberListController.Callback { private val viewModel: RoomBannedMemberListViewModel by fragmentViewModel() private val roomProfileArgs: RoomProfileArgs by args() - override fun getLayoutResId() = R.layout.fragment_room_setting_generic + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomSettingGenericBinding { + return FragmentRoomSettingGenericBinding.inflate(inflater, container, false) + } override fun onUnbanClicked(roomMember: RoomMemberSummary) { viewModel.handle(RoomBannedMemberListAction.QueryInfo(roomMember)) @@ -54,9 +60,9 @@ class RoomBannedMemberListFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) roomMemberListController.callback = this - setupToolbar(roomSettingsToolbar) + setupToolbar(views.roomSettingsToolbar) setupSearchView() - roomSettingsRecyclerView.configureWith(roomMemberListController, hasFixedSize = true) + views.roomSettingsRecyclerView.configureWith(roomMemberListController, hasFixedSize = true) viewModel.observeViewEvents { when (it) { @@ -83,14 +89,14 @@ class RoomBannedMemberListFragment @Inject constructor( } override fun onDestroyView() { - roomSettingsRecyclerView.cleanup() + views.roomSettingsRecyclerView.cleanup() super.onDestroyView() } private fun setupSearchView() { - searchViewAppBarLayout.isVisible = true - searchView.queryHint = getString(R.string.search_banned_user_hint) - searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + views.searchViewAppBarLayout.isVisible = true + views.searchView.queryHint = getString(R.string.search_banned_user_hint) + views.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { return true } @@ -109,8 +115,8 @@ class RoomBannedMemberListFragment @Inject constructor( private fun renderRoomSummary(state: RoomBannedMemberListViewState) { state.roomSummary()?.let { - roomSettingsToolbarTitleView.text = it.displayName - avatarRenderer.render(it.toMatrixItem(), roomSettingsToolbarAvatarImageView) + views.roomSettingsToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), views.roomSettingsToolbarAvatarImageView) } } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt index fb42b8ce27..62fb9e2b02 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roomprofile.members import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.SearchView import androidx.core.view.isVisible @@ -29,10 +31,12 @@ import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomMemberListBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs -import kotlinx.android.synthetic.main.fragment_room_member_list.* -import kotlinx.android.synthetic.main.fragment_room_setting_generic.* + + import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary @@ -44,12 +48,15 @@ class RoomMemberListFragment @Inject constructor( val viewModelFactory: RoomMemberListViewModel.Factory, private val roomMemberListController: RoomMemberListController, private val avatarRenderer: AvatarRenderer -) : VectorBaseFragment(), RoomMemberListController.Callback { +) : VectorBaseFragment(), + RoomMemberListController.Callback { private val viewModel: RoomMemberListViewModel by fragmentViewModel() private val roomProfileArgs: RoomProfileArgs by args() - override fun getLayoutResId() = R.layout.fragment_room_member_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomMemberListBinding { + return FragmentRoomMemberListBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -57,7 +64,7 @@ class RoomMemberListFragment @Inject constructor( setupToolbar(roomSettingsToolbar) setupSearchView() setupInviteUsersButton() - roomSettingsRecyclerView.configureWith(roomMemberListController, hasFixedSize = true) + views.roomSettingsRecyclerView.configureWith(roomMemberListController, hasFixedSize = true) } private fun setupInviteUsersButton() { @@ -65,7 +72,7 @@ class RoomMemberListFragment @Inject constructor( navigator.openInviteUsersToRoom(requireContext(), roomProfileArgs.roomId) } // Hide FAB when list is scrolling - roomSettingsRecyclerView.addOnScrollListener( + views.roomSettingsRecyclerView.addOnScrollListener( object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { when (newState) { @@ -99,7 +106,7 @@ class RoomMemberListFragment @Inject constructor( } override fun onDestroyView() { - roomSettingsRecyclerView.cleanup() + views.roomSettingsRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt index d66599db91..17689c3dfb 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/RoomSettingsFragment.kt @@ -18,9 +18,11 @@ package im.vector.app.features.roomprofile.settings import android.net.Uri import android.os.Bundle +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import com.airbnb.mvrx.args @@ -36,6 +38,7 @@ import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.toast +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.roomprofile.RoomProfileArgs import im.vector.app.features.roomprofile.RoomProfileSharedAction @@ -44,8 +47,8 @@ import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistory import im.vector.app.features.roomprofile.settings.historyvisibility.RoomHistoryVisibilityBottomSheet import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleBottomSheet import im.vector.app.features.roomprofile.settings.joinrule.RoomJoinRuleSharedActionViewModel -import kotlinx.android.synthetic.main.fragment_room_setting_generic.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* + + import org.matrix.android.sdk.api.util.toMatrixItem import java.util.UUID import javax.inject.Inject @@ -56,7 +59,7 @@ class RoomSettingsFragment @Inject constructor( colorProvider: ColorProvider, private val avatarRenderer: AvatarRenderer ) : - VectorBaseFragment(), + VectorBaseFragment(), RoomSettingsController.Callback, OnBackPressed, GalleryOrCameraDialogHelper.Listener { @@ -69,7 +72,9 @@ class RoomSettingsFragment @Inject constructor( private val roomProfileArgs: RoomProfileArgs by args() private val galleryOrCameraDialogHelper = GalleryOrCameraDialogHelper(this, colorProvider) - override fun getLayoutResId() = R.layout.fragment_room_setting_generic + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomSettingGenericBinding { + return FragmentRoomSettingGenericBinding.inflate(inflater, container, false) + } override fun getMenuRes() = R.menu.vector_room_settings @@ -79,10 +84,10 @@ class RoomSettingsFragment @Inject constructor( setupRoomHistoryVisibilitySharedActionViewModel() setupRoomJoinRuleSharedActionViewModel() controller.callback = this - setupToolbar(roomSettingsToolbar) - roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true) - waitingStatusText.setText(R.string.please_wait) - waitingStatusText.isVisible = true + setupToolbar(views.roomSettingsToolbar) + views.roomSettingsRecyclerView.configureWith(controller, hasFixedSize = true) + views.waitingView.waitingStatusText.setText(R.string.please_wait) + views.waitingView.waitingStatusText.isVisible = true viewModel.observeViewEvents { when (it) { @@ -122,7 +127,7 @@ class RoomSettingsFragment @Inject constructor( override fun onDestroyView() { controller.callback = null - roomSettingsRecyclerView.cleanup() + views.roomSettingsRecyclerView.cleanup() super.onDestroyView() } @@ -146,11 +151,11 @@ class RoomSettingsFragment @Inject constructor( } private fun renderRoomSummary(state: RoomSettingsViewState) { - waiting_view.isVisible = state.isLoading + views.waitingView.root.isVisible = state.isLoading state.roomSummary()?.let { - roomSettingsToolbarTitleView.text = it.displayName - avatarRenderer.render(it.toMatrixItem(), roomSettingsToolbarAvatarImageView) + views.roomSettingsToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), views.roomSettingsToolbarAvatarImageView) } invalidateOptionsMenu() diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt index c12dc621a9..76d7115f30 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/historyvisibility/RoomHistoryVisibilityBottomSheet.kt @@ -24,7 +24,7 @@ import com.airbnb.mvrx.withState import im.vector.app.core.di.ScreenComponent import im.vector.app.core.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt index 66c6be6086..c6cb676e1f 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/settings/joinrule/RoomJoinRuleBottomSheet.kt @@ -24,7 +24,7 @@ import com.airbnb.mvrx.withState import im.vector.app.core.di.ScreenComponent import im.vector.app.core.ui.bottomsheet.BottomSheetGeneric import im.vector.app.core.ui.bottomsheet.BottomSheetGenericController -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt index fb53d91e09..c86f58935e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/RoomUploadsFragment.kt @@ -17,11 +17,14 @@ package im.vector.app.features.roomprofile.uploads import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.net.toUri import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState +import com.google.android.material.appbar.AppBarLayout import com.google.android.material.tabs.TabLayoutMediator import im.vector.app.R import im.vector.app.core.extensions.exhaustive @@ -29,10 +32,12 @@ import im.vector.app.core.intent.getMimeTypeFromUri import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.saveMedia import im.vector.app.core.utils.shareMedia +import im.vector.app.databinding.FragmentRoomSettingGenericBinding +import im.vector.app.databinding.FragmentRoomUploadsBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.roomprofile.RoomProfileArgs -import kotlinx.android.synthetic.main.fragment_room_uploads.* + import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject @@ -40,28 +45,31 @@ class RoomUploadsFragment @Inject constructor( private val viewModelFactory: RoomUploadsViewModel.Factory, private val avatarRenderer: AvatarRenderer, private val notificationUtils: NotificationUtils -) : VectorBaseFragment(), RoomUploadsViewModel.Factory by viewModelFactory { +) : VectorBaseFragment(), + RoomUploadsViewModel.Factory by viewModelFactory { private val roomProfileArgs: RoomProfileArgs by args() private val viewModel: RoomUploadsViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_room_uploads + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomUploadsBinding { + return FragmentRoomUploadsBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val sectionsPagerAdapter = RoomUploadsPagerAdapter(this) - roomUploadsViewPager.adapter = sectionsPagerAdapter + views.roomUploadsViewPager.adapter = sectionsPagerAdapter - TabLayoutMediator(roomUploadsTabs, roomUploadsViewPager) { tab, position -> + TabLayoutMediator(views.roomUploadsTabs, views.roomUploadsViewPager) { tab, position -> when (position) { 0 -> tab.text = getString(R.string.uploads_media_title) 1 -> tab.text = getString(R.string.uploads_files_title) } }.attach() - setupToolbar(roomUploadsToolbar) + setupToolbar(views.roomUploadsToolbar) viewModel.observeViewEvents { when (it) { @@ -88,8 +96,11 @@ class RoomUploadsFragment @Inject constructor( private fun renderRoomSummary(state: RoomUploadsViewState) { state.roomSummary()?.let { - roomUploadsToolbarTitleView.text = it.displayName - avatarRenderer.render(it.toMatrixItem(), roomUploadsToolbarAvatarImageView) + views.roomUploadsToolbarTitleView.text = it.displayName + avatarRenderer.render(it.toMatrixItem(), views.roomUploadsToolbarAvatarImageView) } } + + val roomUploadsAppBar: AppBarLayout + get() = views.roomUploadsAppBar } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt index 3c52f2e107..591904c6f4 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/files/RoomUploadsFilesFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.roomprofile.uploads.files import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.content.ContextCompat import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading @@ -30,36 +32,40 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericStateViewRecyclerBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.roomprofile.uploads.RoomUploadsAction import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel -import kotlinx.android.synthetic.main.fragment_generic_state_view_recycler.* + import org.matrix.android.sdk.api.session.room.uploads.UploadEvent import javax.inject.Inject class RoomUploadsFilesFragment @Inject constructor( private val controller: UploadsFileController -) : VectorBaseFragment(), +) : VectorBaseFragment(), UploadsFileController.Listener, StateView.EventCallback { private val uploadsViewModel by parentFragmentViewModel(RoomUploadsViewModel::class) - override fun getLayoutResId() = R.layout.fragment_generic_state_view_recycler + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericStateViewRecyclerBinding { + return FragmentGenericStateViewRecyclerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericStateViewListStateView.contentView = genericStateViewListRecycler - genericStateViewListStateView.eventCallback = this + views.genericStateViewListStateView.contentView = views.genericStateViewListRecycler + views.genericStateViewListStateView.eventCallback = this - genericStateViewListRecycler.trackItemsVisibilityChange() - genericStateViewListRecycler.configureWith(controller, showDivider = true) + views.genericStateViewListRecycler.trackItemsVisibilityChange() + views.genericStateViewListRecycler.configureWith(controller, showDivider = true) controller.listener = this } override fun onDestroyView() { super.onDestroyView() - genericStateViewListRecycler.cleanup() + views.genericStateViewListRecycler.cleanup() controller.listener = null } @@ -88,17 +94,17 @@ class RoomUploadsFilesFragment @Inject constructor( if (state.fileEvents.isEmpty()) { when (state.asyncEventsRequest) { is Loading -> { - genericStateViewListStateView.state = StateView.State.Loading + views.genericStateViewListStateView.state = StateView.State.Loading } is Fail -> { - genericStateViewListStateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncEventsRequest.error)) + views.genericStateViewListStateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncEventsRequest.error)) } is Success -> { if (state.hasMore) { // We need to load more items loadMore() } else { - genericStateViewListStateView.state = StateView.State.Empty( + views.genericStateViewListStateView.state = StateView.State.Empty( title = getString(R.string.uploads_files_no_result), image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_file) ) @@ -106,7 +112,7 @@ class RoomUploadsFilesFragment @Inject constructor( } } } else { - genericStateViewListStateView.state = StateView.State.Content + views.genericStateViewListStateView.state = StateView.State.Content controller.setData(state) } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt index d25277d9f5..32c8f8b470 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.roomprofile.uploads.media import android.os.Bundle import android.util.DisplayMetrics +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.core.util.Pair import androidx.core.view.ViewCompat @@ -35,6 +37,8 @@ import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.StateView import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter +import im.vector.app.databinding.FragmentGenericStateViewRecyclerBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.media.AttachmentData import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.media.VideoContentRenderer @@ -42,8 +46,8 @@ import im.vector.app.features.roomprofile.uploads.RoomUploadsAction import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState -import kotlinx.android.synthetic.main.fragment_generic_state_view_recycler.* -import kotlinx.android.synthetic.main.fragment_room_uploads.* + + import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.getFileUrl @@ -53,24 +57,25 @@ import javax.inject.Inject class RoomUploadsMediaFragment @Inject constructor( private val controller: UploadsMediaController, private val dimensionConverter: DimensionConverter -) : VectorBaseFragment(), +) : VectorBaseFragment(), UploadsMediaController.Listener, StateView.EventCallback { private val uploadsViewModel by parentFragmentViewModel(RoomUploadsViewModel::class) - override fun getLayoutResId() = R.layout.fragment_generic_state_view_recycler + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericStateViewRecyclerBinding { + return FragmentGenericStateViewRecyclerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericStateViewListStateView.contentView = genericStateViewListRecycler - genericStateViewListStateView.eventCallback = this - - genericStateViewListRecycler.trackItemsVisibilityChange() - genericStateViewListRecycler.layoutManager = GridLayoutManager(context, getNumberOfColumns()) - genericStateViewListRecycler.adapter = controller.adapter - genericStateViewListRecycler.setHasFixedSize(true) + views.genericStateViewListStateView.contentView = views.genericStateViewListRecycler + views.genericStateViewListStateView.eventCallback = this + views.genericStateViewListRecycler.trackItemsVisibilityChange() + views.genericStateViewListRecycler.layoutManager = GridLayoutManager(context, getNumberOfColumns()) + views.genericStateViewListRecycler.adapter = controller.adapter + views.genericStateViewListRecycler.setHasFixedSize(true) controller.listener = this } @@ -83,7 +88,7 @@ class RoomUploadsMediaFragment @Inject constructor( override fun onDestroyView() { super.onDestroyView() - genericStateViewListRecycler.cleanup() + views.genericStateViewListRecycler.cleanup() controller.listener = null } @@ -181,17 +186,17 @@ class RoomUploadsMediaFragment @Inject constructor( if (state.mediaEvents.isEmpty()) { when (state.asyncEventsRequest) { is Loading -> { - genericStateViewListStateView.state = StateView.State.Loading + views.genericStateViewListStateView.state = StateView.State.Loading } is Fail -> { - genericStateViewListStateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncEventsRequest.error)) + views.genericStateViewListStateView.state = StateView.State.Error(errorFormatter.toHumanReadable(state.asyncEventsRequest.error)) } is Success -> { if (state.hasMore) { // We need to load more items loadMore() } else { - genericStateViewListStateView.state = StateView.State.Empty( + views.genericStateViewListStateView.state = StateView.State.Empty( title = getString(R.string.uploads_media_no_result), image = ContextCompat.getDrawable(requireContext(), R.drawable.ic_image) ) @@ -199,7 +204,7 @@ class RoomUploadsMediaFragment @Inject constructor( } } } else { - genericStateViewListStateView.state = StateView.State.Content + views.genericStateViewListStateView.state = StateView.State.Content controller.setData(state) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt index 28702940ee..0581f06c13 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsActivity.kt @@ -25,8 +25,9 @@ import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivityVectorSettingsBinding import im.vector.app.features.settings.devices.VectorSettingsDevicesFragment -import kotlinx.android.synthetic.main.activity_vector_settings.* + import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session import timber.log.Timber @@ -35,12 +36,12 @@ import javax.inject.Inject /** * Displays the client settings. */ -class VectorSettingsActivity : VectorBaseActivity(), +class VectorSettingsActivity : VectorBaseActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, FragmentManager.OnBackStackChangedListener, VectorSettingsFragmentInteractionListener { - override fun getLayoutRes() = R.layout.activity_vector_settings + override fun getBinding() = ActivityVectorSettingsBinding.inflate(layoutInflater) override fun getTitleRes() = R.string.title_activity_settings @@ -55,7 +56,7 @@ class VectorSettingsActivity : VectorBaseActivity(), } override fun initUiAndData() { - configureToolbar(settingsToolbar) + configureToolbar(views.settingsToolbar) if (isFirstCreation()) { // display the fragment diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt index add6fba38c..232ea063a8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsBaseFragment.kt @@ -35,8 +35,8 @@ import timber.log.Timber abstract class VectorSettingsBaseFragment : PreferenceFragmentCompat(), HasScreenInjector { - val vectorActivity: VectorBaseActivity by lazy { - activity as VectorBaseActivity + val vectorActivity: VectorBaseActivity<*> by lazy { + activity as VectorBaseActivity<*> } private var mLoadingView: View? = null diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt index c458d6a74c..e6f92e1eea 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsNotificationsTroubleshootFragment.kt @@ -21,7 +21,9 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.localbroadcastmanager.content.LocalBroadcastManager import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager @@ -31,12 +33,14 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentRoomSettingGenericBinding +import im.vector.app.databinding.FragmentSettingsNotificationsTroubleshootBinding import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.rageshake.BugReporter import im.vector.app.features.settings.troubleshoot.NotificationTroubleshootTestManager import im.vector.app.features.settings.troubleshoot.TroubleshootTest import im.vector.app.push.fcm.NotificationTroubleshootTestManagerFactory -import kotlinx.android.synthetic.main.fragment_settings_notifications_troubleshoot.* + import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject @@ -44,12 +48,14 @@ import javax.inject.Inject class VectorSettingsNotificationsTroubleshootFragment @Inject constructor( private val bugReporter: BugReporter, private val testManagerFactory: NotificationTroubleshootTestManagerFactory -) : VectorBaseFragment() { +) : VectorBaseFragment() { private var testManager: NotificationTroubleshootTestManager? = null // members - override fun getLayoutResId() = R.layout.fragment_settings_notifications_troubleshoot + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentSettingsNotificationsTroubleshootBinding { + return FragmentSettingsNotificationsTroubleshootBinding.inflate(inflater, container, false) + } private var interactionListener: VectorSettingsFragmentInteractionListener? = null @@ -143,7 +149,7 @@ class VectorSettingsNotificationsTroubleshootFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_notification_troubleshoot) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_notification_troubleshoot) tryOrNull("Unable to register the receiver") { LocalBroadcastManager.getInstance(requireContext()) diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt index e48ab337d6..8449215a09 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.settings.account.deactivation import android.content.Context import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.jakewharton.rxbinding3.widget.textChanges @@ -27,23 +29,27 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.showPassword import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentDeactivateAccountBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.settings.VectorSettingsActivity -import kotlinx.android.synthetic.main.fragment_deactivate_account.* + import javax.inject.Inject class DeactivateAccountFragment @Inject constructor( val viewModelFactory: DeactivateAccountViewModel.Factory -) : VectorBaseFragment() { +) : VectorBaseFragment() { private val viewModel: DeactivateAccountViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_deactivate_account + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDeactivateAccountBinding { + return FragmentDeactivateAccountBinding.inflate(inflater, container, false) + } override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.deactivate_account_title) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.deactivate_account_title) } private var settingsActivity: VectorSettingsActivity? = null diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt index f21ec2e8f4..fbfe869ecd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsFragment.kt @@ -16,8 +16,11 @@ package im.vector.app.features.settings.crosssigning import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -26,7 +29,9 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding + import javax.inject.Inject /** @@ -35,9 +40,12 @@ import javax.inject.Inject class CrossSigningSettingsFragment @Inject constructor( private val controller: CrossSigningSettingsController, val viewModelFactory: CrossSigningSettingsViewModel.Factory -) : VectorBaseFragment(), CrossSigningSettingsController.InteractionListener { +) : VectorBaseFragment(), + CrossSigningSettingsController.InteractionListener { - 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: CrossSigningSettingsViewModel by fragmentViewModel() @@ -60,7 +68,7 @@ class CrossSigningSettingsFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.encryption_information_cross_signing_state) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.encryption_information_cross_signing_state) } override fun invalidate() = withState(viewModel) { state -> @@ -68,12 +76,12 @@ class CrossSigningSettingsFragment @Inject constructor( } private fun setupRecyclerView() { - genericRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) + views.genericRecyclerView.configureWith(controller, hasFixedSize = false, disableItemAnimation = true) controller.interactionListener = this } override fun onDestroyView() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() controller.interactionListener = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt index 7cc25170cb..c93d6d5652 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheet.kt @@ -17,7 +17,9 @@ package im.vector.app.features.settings.devices import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.fragmentViewModel @@ -28,8 +30,10 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.bottom_sheet_generic_list_with_title.* +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetGenericListWithTitleBinding +import kotlinx.parcelize.Parcelize + import javax.inject.Inject @Parcelize @@ -38,7 +42,9 @@ data class DeviceVerificationInfoArgs( val deviceId: String ) : Parcelable -class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), DeviceVerificationInfoBottomSheetController.Callback { +class DeviceVerificationInfoBottomSheet : + VectorBaseBottomSheetDialogFragment(), + DeviceVerificationInfoBottomSheetController.Callback { private val viewModel: DeviceVerificationInfoBottomSheetViewModel by fragmentViewModel(DeviceVerificationInfoBottomSheetViewModel::class) @@ -52,20 +58,22 @@ class DeviceVerificationInfoBottomSheet : VectorBaseBottomSheetDialogFragment(), @Inject lateinit var controller: DeviceVerificationInfoBottomSheetController - override fun getLayoutResId() = R.layout.bottom_sheet_generic_list_with_title + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetGenericListWithTitleBinding { + return BottomSheetGenericListWithTitleBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - bottomSheetRecyclerView.configureWith( + views.bottomSheetRecyclerView.configureWith( controller, showDivider = false, hasFixedSize = false) controller.callback = this - bottomSheetTitle.isVisible = false + views.bottomSheetTitle.isVisible = false } override fun onDestroyView() { - bottomSheetRecyclerView.cleanup() + views.bottomSheetRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index 520a63d1a9..904024d031 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -17,9 +17,12 @@ package im.vector.app.features.settings.devices import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import com.airbnb.mvrx.Async import com.airbnb.mvrx.Loading @@ -33,9 +36,11 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomSettingGenericBinding import im.vector.app.features.crypto.verification.VerificationBottomSheet -import kotlinx.android.synthetic.main.fragment_generic_recycler.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* + + import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import javax.inject.Inject @@ -45,23 +50,26 @@ import javax.inject.Inject class VectorSettingsDevicesFragment @Inject constructor( val devicesViewModelFactory: DevicesViewModel.Factory, private val devicesController: DevicesController -) : VectorBaseFragment(), DevicesController.Callback { +) : VectorBaseFragment(), + DevicesController.Callback { // used to avoid requesting to enter the password for each deletion // Note: Sonar does not like to use password for member name. private var mAccountPass: String = "" - 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: DevicesViewModel by fragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - waitingStatusText.setText(R.string.please_wait) - waitingStatusText.isVisible = true + views.waitingView.waitingStatusText.setText(R.string.please_wait) + views.waitingView.waitingStatusText.isVisible = true devicesController.callback = this - genericRecyclerView.configureWith(devicesController, showDivider = true) + views.genericRecyclerView.configureWith(devicesController, showDivider = true) viewModel.observeViewEvents { when (it) { is DevicesViewEvents.Loading -> showLoading(it.message) @@ -97,13 +105,13 @@ class VectorSettingsDevicesFragment @Inject constructor( override fun onDestroyView() { devicesController.callback = null - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroyView() } override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_active_sessions_manage) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_active_sessions_manage) viewModel.handle(DevicesAction.Refresh) } @@ -171,9 +179,9 @@ class VectorSettingsDevicesFragment @Inject constructor( } private fun handleRequestStatus(unIgnoreRequest: Async) { - when (unIgnoreRequest) { - is Loading -> waiting_view.isVisible = true - else -> waiting_view.isVisible = false + views.waitingView.root.isVisible = when (unIgnoreRequest) { + is Loading -> true + else -> false } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt index 40b910c1ab..3f3a2283b8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt @@ -18,8 +18,11 @@ package im.vector.app.features.settings.devtools import android.content.DialogInterface import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -30,7 +33,8 @@ import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.createJSonViewerStyleProvider -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.internal.di.MoshiProvider @@ -40,15 +44,18 @@ class AccountDataFragment @Inject constructor( val viewModelFactory: AccountDataViewModel.Factory, private val epoxyController: AccountDataEpoxyController, private val colorProvider: ColorProvider -) : VectorBaseFragment(), AccountDataEpoxyController.InteractionListener { +) : VectorBaseFragment(), + AccountDataEpoxyController.InteractionListener { - 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: AccountDataViewModel by fragmentViewModel(AccountDataViewModel::class) override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_account_data) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_account_data) } override fun invalidate() = withState(viewModel) { state -> @@ -57,13 +64,13 @@ class AccountDataFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) epoxyController.interactionListener = this } override fun onDestroyView() { super.onDestroyView() - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() epoxyController.interactionListener = null } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt index af8881ba92..8ac692025f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsPaperTrailFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.settings.devtools import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -26,7 +28,8 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.resources.ColorProvider import im.vector.app.core.utils.createJSonViewerStyleProvider -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.matrix.android.sdk.api.session.events.model.Event import javax.inject.Inject @@ -35,9 +38,12 @@ class GossipingEventsPaperTrailFragment @Inject constructor( val viewModelFactory: GossipingEventsPaperTrailViewModel.Factory, private val epoxyController: GossipingTrailPagedEpoxyController, private val colorProvider: ColorProvider -) : VectorBaseFragment(), GossipingTrailPagedEpoxyController.InteractionListener { +) : VectorBaseFragment(), + GossipingTrailPagedEpoxyController.InteractionListener { - 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: GossipingEventsPaperTrailViewModel by fragmentViewModel(GossipingEventsPaperTrailViewModel::class) @@ -50,13 +56,13 @@ class GossipingEventsPaperTrailFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) epoxyController.interactionListener = this } override fun onDestroyView() { super.onDestroyView() - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() epoxyController.interactionListener = null } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt index 6e205ceceb..194b2b403f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestListFragment.kt @@ -17,22 +17,27 @@ package im.vector.app.features.settings.devtools import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject class IncomingKeyRequestListFragment @Inject constructor( val viewModelFactory: KeyRequestListViewModel.Factory, private val epoxyController: IncomingKeyRequestPagedController -) : VectorBaseFragment() { +) : VectorBaseFragment() { - 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: KeyRequestListViewModel by fragmentViewModel(KeyRequestListViewModel::class) @@ -45,11 +50,11 @@ class IncomingKeyRequestListFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) } override fun onDestroyView() { super.onDestroyView() - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt index ff91d9bba3..e9070ed7d8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestsFragment.kt @@ -18,8 +18,11 @@ package im.vector.app.features.settings.devtools import android.app.Activity import android.os.Bundle +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter @@ -35,18 +38,22 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.selectTxtFileToWrite -import kotlinx.android.synthetic.main.fragment_devtool_keyrequests.* +import im.vector.app.databinding.FragmentDevtoolKeyrequestsBinding +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject class KeyRequestsFragment @Inject constructor( - val viewModelFactory: KeyRequestViewModel.Factory) : VectorBaseFragment() { + val viewModelFactory: KeyRequestViewModel.Factory) : VectorBaseFragment() { - override fun getLayoutResId(): Int = R.layout.fragment_devtool_keyrequests + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentDevtoolKeyrequestsBinding { + return FragmentDevtoolKeyrequestsBinding.inflate(inflater, container, false) + } override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.key_share_request) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.key_share_request) } private var mPagerAdapter: KeyReqPagerAdapter? = null @@ -70,8 +77,8 @@ class KeyRequestsFragment @Inject constructor( override fun invalidate() = withState(viewModel) { when (it.exporting) { - is Loading -> exportWaitingView.isVisible = true - else -> exportWaitingView.isVisible = false + is Loading -> views.exportWaitingView.isVisible = true + else -> views.exportWaitingView.isVisible = false } } @@ -83,10 +90,10 @@ class KeyRequestsFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) mPagerAdapter = KeyReqPagerAdapter(this) - devToolKeyRequestPager.adapter = mPagerAdapter - devToolKeyRequestPager.registerOnPageChangeCallback(pageAdapterListener) + views.devToolKeyRequestPager.adapter = mPagerAdapter + views.devToolKeyRequestPager.registerOnPageChangeCallback(pageAdapterListener) - TabLayoutMediator(devToolKeyRequestTabs, devToolKeyRequestPager) { tab, position -> + TabLayoutMediator(views.devToolKeyRequestTabs, views.devToolKeyRequestPager) { tab, position -> when (position) { 0 -> { tab.text = "Outgoing" @@ -113,7 +120,7 @@ class KeyRequestsFragment @Inject constructor( } override fun onDestroyView() { - devToolKeyRequestPager.unregisterOnPageChangeCallback(pageAdapterListener) + views.devToolKeyRequestPager.unregisterOnPageChangeCallback(pageAdapterListener) mPagerAdapter = null super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt index 20132d8047..b0eefe195d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestListFragment.kt @@ -17,22 +17,28 @@ package im.vector.app.features.settings.devtools import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject class OutgoingKeyRequestListFragment @Inject constructor( val viewModelFactory: KeyRequestListViewModel.Factory, private val epoxyController: OutgoingKeyRequestPagedController -) : VectorBaseFragment() { +) : VectorBaseFragment() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } - override fun getLayoutResId() = R.layout.fragment_generic_recycler private val viewModel: KeyRequestListViewModel by fragmentViewModel(KeyRequestListViewModel::class) override fun invalidate() = withState(viewModel) { state -> @@ -41,13 +47,13 @@ class OutgoingKeyRequestListFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) // epoxyController.interactionListener = this } override fun onDestroyView() { super.onDestroyView() - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() // epoxyController.interactionListener = null } } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 8bca7243a6..e766854d8c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -17,8 +17,11 @@ package im.vector.app.features.settings.ignored import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import com.airbnb.mvrx.Async import com.airbnb.mvrx.Loading @@ -30,26 +33,29 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* -import kotlinx.android.synthetic.main.merge_overlay_waiting_view.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject class VectorSettingsIgnoredUsersFragment @Inject constructor( val ignoredUsersViewModelFactory: IgnoredUsersViewModel.Factory, private val ignoredUsersController: IgnoredUsersController -) : VectorBaseFragment(), IgnoredUsersController.Callback { +) : VectorBaseFragment(), + IgnoredUsersController.Callback { - 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: IgnoredUsersViewModel by fragmentViewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - waitingStatusText.setText(R.string.please_wait) - waitingStatusText.isVisible = true + views.waitingView.waitingStatusText.setText(R.string.please_wait) + views.waitingView.waitingStatusText.isVisible = true ignoredUsersController.callback = this - genericRecyclerView.configureWith(ignoredUsersController) + views.genericRecyclerView.configureWith(ignoredUsersController) viewModel.observeViewEvents { when (it) { is IgnoredUsersViewEvents.Loading -> showLoading(it.message) @@ -60,14 +66,14 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( override fun onDestroyView() { ignoredUsersController.callback = null - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroyView() } override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_ignored_users) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_ignored_users) } override fun onUserIdClicked(userId: String) { @@ -91,9 +97,9 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( } private fun handleUnIgnoreRequestStatus(unIgnoreRequest: Async) { - when (unIgnoreRequest) { - is Loading -> waiting_view.isVisible = true - else -> waiting_view.isVisible = false + views.waitingView.root.isVisible = when (unIgnoreRequest) { + is Loading -> true + else -> false } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt index e156528d3d..68d940cdd8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/locale/LocalePickerFragment.kt @@ -17,7 +17,10 @@ package im.vector.app.features.settings.locale import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -27,22 +30,28 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.restart import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_locale_picker.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentLocalePickerBinding + import java.util.Locale import javax.inject.Inject class LocalePickerFragment @Inject constructor( private val viewModelFactory: LocalePickerViewModel.Factory, private val controller: LocalePickerController -) : VectorBaseFragment(), LocalePickerViewModel.Factory by viewModelFactory, LocalePickerController.Listener { +) : VectorBaseFragment(), + LocalePickerViewModel.Factory by viewModelFactory, + LocalePickerController.Listener { private val viewModel: LocalePickerViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_locale_picker + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocalePickerBinding { + return FragmentLocalePickerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - localeRecyclerView.configureWith(controller) + views.localeRecyclerView.configureWith(controller) controller.listener = this viewModel.observeViewEvents { @@ -56,7 +65,7 @@ class LocalePickerFragment @Inject constructor( override fun onDestroyView() { super.onDestroyView() - localeRecyclerView.cleanup() + views.localeRecyclerView.cleanup() controller.listener = null } @@ -75,6 +84,6 @@ class LocalePickerFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_select_language) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_select_language) } } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt index 0075d8ef5a..f2823c8074 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushGatewaysFragment.kt @@ -17,8 +17,11 @@ package im.vector.app.features.settings.push import android.os.Bundle +import android.view.LayoutInflater import android.view.MenuItem import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -26,16 +29,19 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject // Referenced in vector_settings_notifications.xml class PushGatewaysFragment @Inject constructor( val pushGatewaysViewModelFactory: PushGatewaysViewModel.Factory, private val epoxyController: PushGateWayController -) : VectorBaseFragment() { +) : VectorBaseFragment() { - 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: PushGatewaysViewModel by fragmentViewModel(PushGatewaysViewModel::class) @@ -54,16 +60,16 @@ class PushGatewaysFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_notifications_targets) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_notifications_targets) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) } override fun onDestroyView() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt index c5ad04380b..340f26a892 100644 --- a/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/push/PushRulesFragment.kt @@ -16,7 +16,10 @@ package im.vector.app.features.settings.push import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -24,30 +27,33 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import javax.inject.Inject // Referenced in vector_settings_notifications.xml class PushRulesFragment @Inject constructor( private val epoxyController: PushRulesController -) : VectorBaseFragment() { +) : VectorBaseFragment() { - 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: PushRulesViewModel by fragmentViewModel(PushRulesViewModel::class) override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_push_rules) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_push_rules) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController, showDivider = true) + views.genericRecyclerView.configureWith(epoxyController, showDivider = true) } override fun onDestroyView() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() super.onDestroyView() } diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt index 12ff51dcbd..dd615eddf6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsFragment.kt @@ -18,8 +18,11 @@ package im.vector.app.features.settings.threepids import android.content.DialogInterface import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -35,7 +38,8 @@ import im.vector.app.core.extensions.isMsisdn import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment -import kotlinx.android.synthetic.main.fragment_generic_recycler.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding + import org.matrix.android.sdk.api.session.identity.ThreePid import javax.inject.Inject @@ -43,18 +47,20 @@ class ThreePidsSettingsFragment @Inject constructor( private val viewModelFactory: ThreePidsSettingsViewModel.Factory, private val epoxyController: ThreePidsSettingsController ) : - VectorBaseFragment(), + VectorBaseFragment(), OnBackPressed, ThreePidsSettingsViewModel.Factory by viewModelFactory, ThreePidsSettingsController.InteractionListener { private val viewModel: ThreePidsSettingsViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_generic_recycler + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - genericRecyclerView.configureWith(epoxyController) + views.genericRecyclerView.configureWith(epoxyController) epoxyController.interactionListener = this viewModel.observeViewEvents { @@ -73,13 +79,13 @@ class ThreePidsSettingsFragment @Inject constructor( override fun onDestroyView() { super.onDestroyView() - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() epoxyController.interactionListener = null } override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_emails_and_phone_numbers_title) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.settings_emails_and_phone_numbers_title) } override fun invalidate() = withState(viewModel) { state -> diff --git a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt index 321a2b3e94..65f1a05f29 100644 --- a/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt +++ b/vector/src/main/java/im/vector/app/features/settings/troubleshoot/NotificationTroubleshootRecyclerViewAdapter.kt @@ -22,7 +22,7 @@ import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView import im.vector.app.R import im.vector.app.features.themes.ThemeUtils -import kotlinx.android.synthetic.main.item_notification_troubleshoot.view.* + class NotificationTroubleshootRecyclerViewAdapter(val tests: ArrayList) : RecyclerView.Adapter() { diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt index 3977dfb990..5bac7744c5 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareActivity.kt @@ -21,10 +21,11 @@ import im.vector.app.R import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding -class IncomingShareActivity : VectorBaseActivity(), ToolbarConfigurable { +class IncomingShareActivity : VectorBaseActivity(), ToolbarConfigurable { - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun initUiAndData() { if (isFirstCreation()) { diff --git a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt index 92e383f8d1..7d0bee2efc 100644 --- a/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt +++ b/vector/src/main/java/im/vector/app/features/share/IncomingShareFragment.kt @@ -20,7 +20,9 @@ import android.app.Activity import android.content.ClipDescription import android.content.Intent import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog @@ -35,11 +37,13 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentIncomingShareBinding import im.vector.app.features.attachments.AttachmentsHelper import im.vector.app.features.attachments.preview.AttachmentsPreviewActivity import im.vector.app.features.attachments.preview.AttachmentsPreviewArgs import im.vector.app.features.login.LoginActivity -import kotlinx.android.synthetic.main.fragment_incoming_share.* + import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject @@ -52,12 +56,17 @@ class IncomingShareFragment @Inject constructor( val incomingShareViewModelFactory: IncomingShareViewModel.Factory, private val incomingShareController: IncomingShareController, private val sessionHolder: ActiveSessionHolder -) : VectorBaseFragment(), AttachmentsHelper.Callback, IncomingShareController.Callback { +) : + VectorBaseFragment(), + AttachmentsHelper.Callback, + IncomingShareController.Callback { private lateinit var attachmentsHelper: AttachmentsHelper private val viewModel: IncomingShareViewModel by fragmentViewModel() - override fun getLayoutResId() = R.layout.fragment_incoming_share + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentIncomingShareBinding { + return FragmentIncomingShareBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { // If we are not logged in, stop the sharing process and open login screen. @@ -68,7 +77,7 @@ class IncomingShareFragment @Inject constructor( } super.onViewCreated(view, savedInstanceState) setupRecyclerView() - setupToolbar(incomingShareToolbar) + setupToolbar(views.incomingShareToolbar) attachmentsHelper = AttachmentsHelper(requireContext(), this).register() viewModel.observeViewEvents { @@ -103,7 +112,7 @@ class IncomingShareFragment @Inject constructor( cannotManageShare(R.string.error_handling_incoming_share) } - incomingShareSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { + views.incomingShareSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { override fun onQueryTextSubmit(query: String): Boolean { return true } @@ -113,7 +122,7 @@ class IncomingShareFragment @Inject constructor( return true } }) - sendShareButton.setOnClickListener { _ -> + views.sendShareButton.setOnClickListener { _ -> handleSendShare() } } @@ -154,12 +163,12 @@ class IncomingShareFragment @Inject constructor( override fun onDestroyView() { incomingShareController.callback = null - incomingShareRoomList.cleanup() + views.incomingShareRoomList.cleanup() super.onDestroyView() } private fun setupRecyclerView() { - incomingShareRoomList.configureWith(incomingShareController, hasFixedSize = true) + views.incomingShareRoomList.configureWith(incomingShareController, hasFixedSize = true) incomingShareController.callback = this } @@ -210,7 +219,7 @@ class IncomingShareFragment @Inject constructor( } override fun invalidate() = withState(viewModel) { - sendShareButton.isVisible = it.isInMultiSelectionMode + views.sendShareButton.isVisible = it.isInMultiSelectionMode incomingShareController.setData(it) } diff --git a/vector/src/main/java/im/vector/app/features/share/SharedData.kt b/vector/src/main/java/im/vector/app/features/share/SharedData.kt index 02d00ae401..ca0162658f 100644 --- a/vector/src/main/java/im/vector/app/features/share/SharedData.kt +++ b/vector/src/main/java/im/vector/app/features/share/SharedData.kt @@ -17,7 +17,7 @@ package im.vector.app.features.share import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.content.ContentAttachmentData sealed class SharedData : Parcelable { diff --git a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt index c04fe8153b..9f013cda30 100644 --- a/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/hard/SignedOutActivity.kt @@ -21,18 +21,20 @@ import android.content.Intent import android.os.Bundle import im.vector.app.R import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySignedOutBinding +import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs -import kotlinx.android.synthetic.main.activity_signed_out.* + import org.matrix.android.sdk.api.failure.GlobalError import timber.log.Timber /** * In this screen, the user is viewing a message informing that he has been logged out */ -class SignedOutActivity : VectorBaseActivity() { +class SignedOutActivity : VectorBaseActivity() { - override fun getLayoutRes() = R.layout.activity_signed_out + override fun getBinding() = ActivitySignedOutBinding.inflate(layoutInflater) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -41,7 +43,7 @@ class SignedOutActivity : VectorBaseActivity() { } private fun setupViews() { - signedOutSubmit.setOnClickListener { submit() } + views.signedOutSubmit.setOnClickListener { submit() } } private fun submit() { diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt index 5fb7a3e315..bbb6359aa1 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutActivity.kt @@ -30,7 +30,7 @@ import im.vector.app.core.extensions.replaceFragment import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.login.LoginActivity -import kotlinx.android.synthetic.main.activity_login.* + import org.matrix.android.sdk.api.failure.GlobalError import org.matrix.android.sdk.api.session.Session import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt index b85c9a8763..b40a02d3dd 100644 --- a/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt +++ b/vector/src/main/java/im/vector/app/features/signout/soft/SoftLogoutFragment.kt @@ -18,7 +18,9 @@ package im.vector.app.features.signout.soft import android.content.DialogInterface import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState @@ -27,11 +29,12 @@ import im.vector.app.core.dialogs.withColoredButton import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.hideKeyboard +import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.login.AbstractLoginFragment import im.vector.app.features.login.LoginAction import im.vector.app.features.login.LoginMode import im.vector.app.features.login.LoginViewEvents -import kotlinx.android.synthetic.main.fragment_generic_recycler.* + import javax.inject.Inject /** @@ -41,11 +44,14 @@ import javax.inject.Inject */ class SoftLogoutFragment @Inject constructor( private val softLogoutController: SoftLogoutController -) : AbstractLoginFragment(), SoftLogoutController.Listener { +) : AbstractLoginFragment(), + SoftLogoutController.Listener { private val softLogoutViewModel: SoftLogoutViewModel by activityViewModel() - override fun getLayoutResId() = R.layout.fragment_generic_recycler + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding { + return FragmentGenericRecyclerBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -83,12 +89,12 @@ class SoftLogoutFragment @Inject constructor( } private fun setupRecyclerView() { - genericRecyclerView.configureWith(softLogoutController) + views.genericRecyclerView.configureWith(softLogoutController) softLogoutController.listener = this } override fun onDestroyView() { - genericRecyclerView.cleanup() + views.genericRecyclerView.cleanup() softLogoutController.listener = null super.onDestroyView() } @@ -134,7 +140,7 @@ class SoftLogoutFragment @Inject constructor( } private fun cleanupUi() { - genericRecyclerView.hideKeyboard() + views.genericRecyclerView.hideKeyboard() } override fun forgetPasswordClicked() { diff --git a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt index e5e28dcabb..c6bcb0a4e2 100755 --- a/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt +++ b/vector/src/main/java/im/vector/app/features/sync/widget/SyncStateView.kt @@ -23,7 +23,7 @@ import android.widget.FrameLayout import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.utils.isAirplaneModeOn -import kotlinx.android.synthetic.main.view_sync_state.view.* + import org.matrix.android.sdk.api.session.sync.SyncState class SyncStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) diff --git a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt index 10fcb65e12..97fa4710e0 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ReviewTermsFragment.kt @@ -16,7 +16,9 @@ package im.vector.app.features.terms import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import androidx.core.view.isVisible import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success @@ -30,17 +32,22 @@ import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.openUrlInChromeCustomTab -import kotlinx.android.synthetic.main.fragment_review_terms.* +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentReviewTermsBinding + import org.matrix.android.sdk.api.session.terms.TermsService import javax.inject.Inject class ReviewTermsFragment @Inject constructor( private val termsController: TermsController -) : VectorBaseFragment(), TermsController.Listener { +) : VectorBaseFragment(), + TermsController.Listener { private val reviewTermsViewModel: ReviewTermsViewModel by activityViewModel() - override fun getLayoutResId() = R.layout.fragment_review_terms + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentReviewTermsBinding { + return FragmentReviewTermsBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -79,7 +86,7 @@ class ReviewTermsFragment @Inject constructor( override fun onResume() { super.onResume() - (activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.terms_of_service) + (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.terms_of_service) } override fun invalidate() = withState(reviewTermsViewModel) { state -> diff --git a/vector/src/main/java/im/vector/app/features/terms/ServiceTermsArgs.kt b/vector/src/main/java/im/vector/app/features/terms/ServiceTermsArgs.kt index 50c9568204..af3f5aba11 100644 --- a/vector/src/main/java/im/vector/app/features/terms/ServiceTermsArgs.kt +++ b/vector/src/main/java/im/vector/app/features/terms/ServiceTermsArgs.kt @@ -16,7 +16,7 @@ package im.vector.app.features.terms import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.terms.TermsService @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt b/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt index 782d7e1c04..4a060c0fcc 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/ScanUserCodeFragment.kt @@ -20,7 +20,9 @@ import android.Manifest import android.app.Activity import android.content.pm.PackageManager import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Toast import androidx.core.content.ContextCompat import com.airbnb.mvrx.activityViewModel @@ -32,18 +34,22 @@ import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentQrCodeScannerWithButtonBinding import im.vector.lib.multipicker.MultiPicker import im.vector.lib.multipicker.utils.ImageUtils -import kotlinx.android.synthetic.main.fragment_qr_code_scanner_with_button.* + import me.dm7.barcodescanner.zxing.ZXingScannerView import org.matrix.android.sdk.api.extensions.tryOrNull import javax.inject.Inject class ScanUserCodeFragment @Inject constructor() - : VectorBaseFragment(), + : VectorBaseFragment(), ZXingScannerView.ResultHandler { - override fun getLayoutResId() = R.layout.fragment_qr_code_scanner_with_button + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentQrCodeScannerWithButtonBinding { + return FragmentQrCodeScannerWithButtonBinding.inflate(inflater, container, false) + } val sharedViewModel: UserCodeSharedViewModel by activityViewModel() diff --git a/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt b/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt index db6d636b9a..3aadd6c9bf 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/ShowUserCodeFragment.kt @@ -17,7 +17,9 @@ package im.vector.app.features.usercode import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState import im.vector.app.R @@ -27,15 +29,19 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.core.utils.checkPermissions import im.vector.app.core.utils.registerForPermissionsResult import im.vector.app.core.utils.startSharePlainTextIntent +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentUserCodeShowBinding import im.vector.app.features.home.AvatarRenderer -import kotlinx.android.synthetic.main.fragment_user_code_show.* + import javax.inject.Inject class ShowUserCodeFragment @Inject constructor( private val avatarRenderer: AvatarRenderer -) : VectorBaseFragment() { +) : VectorBaseFragment() { - override fun getLayoutResId() = R.layout.fragment_user_code_show + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentUserCodeShowBinding { + return FragmentUserCodeShowBinding.inflate(inflater, container, false) + } val sharedViewModel: UserCodeSharedViewModel by activityViewModel() @@ -49,15 +55,15 @@ class ShowUserCodeFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - showUserCodeClose.debouncedClicks { + views.showUserCodeClose.debouncedClicks { sharedViewModel.handle(UserCodeActions.DismissAction) } - showUserCodeScanButton.debouncedClicks { + views.showUserCodeScanButton.debouncedClicks { if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, requireActivity(), openCameraActivityResultLauncher)) { doOpenQRCodeScanner() } } - showUserCodeShareButton.debouncedClicks { + views.showUserCodeShareButton.debouncedClicks { sharedViewModel.handle(UserCodeActions.ShareByText) } @@ -79,9 +85,9 @@ class ShowUserCodeFragment @Inject constructor( } override fun invalidate() = withState(sharedViewModel) { state -> - state.matrixItem?.let { avatarRenderer.render(it, showUserCodeAvatar) } - state.shareLink?.let { showUserCodeQRImage.setData(it) } - showUserCodeCardNameText.setTextOrHide(state.matrixItem?.displayName) - showUserCodeCardUserIdText.setTextOrHide(state.matrixItem?.id) + state.matrixItem?.let { avatarRenderer.render(it, views.showUserCodeAvatar) } + state.shareLink?.let { views.showUserCodeQRImage.setData(it) } + views.showUserCodeCardNameText.setTextOrHide(state.matrixItem?.displayName) + views.showUserCodeCardUserIdText.setTextOrHide(state.matrixItem?.id) } } diff --git a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt index 547e2d939f..0706fd296b 100644 --- a/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/usercode/UserCodeActivity.kt @@ -33,14 +33,16 @@ import im.vector.app.core.extensions.commitTransaction import im.vector.app.core.extensions.exhaustive import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.onPermissionDeniedSnackbar +import im.vector.app.databinding.ActivitySimpleBinding import im.vector.app.features.matrixto.MatrixToBottomSheet -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.activity_simple.* +import kotlinx.parcelize.Parcelize + import javax.inject.Inject import kotlin.reflect.KClass -class UserCodeActivity - : VectorBaseActivity(), UserCodeSharedViewModel.Factory, MatrixToBottomSheet.InteractionListener { +class UserCodeActivity : VectorBaseActivity(), + UserCodeSharedViewModel.Factory, + MatrixToBottomSheet.InteractionListener { @Inject lateinit var viewModelFactory: UserCodeSharedViewModel.Factory @@ -51,7 +53,7 @@ class UserCodeActivity val userId: String ) : Parcelable - override fun getLayoutRes() = R.layout.activity_simple + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) override fun injectWith(injector: ScreenComponent) { injector.inject(this) @@ -79,8 +81,8 @@ class UserCodeActivity sharedViewModel.observeViewEvents { when (it) { UserCodeShareViewEvents.Dismiss -> ActivityCompat.finishAfterTransition(this) - UserCodeShareViewEvents.ShowWaitingScreen -> simpleActivityWaitingView.isVisible = true - UserCodeShareViewEvents.HideWaitingScreen -> simpleActivityWaitingView.isVisible = false + UserCodeShareViewEvents.ShowWaitingScreen -> views.simpleActivityWaitingView.isVisible = true + UserCodeShareViewEvents.HideWaitingScreen -> views.simpleActivityWaitingView.isVisible = false is UserCodeShareViewEvents.ToastMessage -> Toast.makeText(this, it.message, Toast.LENGTH_LONG).show() is UserCodeShareViewEvents.NavigateToRoom -> navigator.openRoom(this, it.roomId) UserCodeShareViewEvents.CameraPermissionNotGranted -> onPermissionDeniedSnackbar(R.string.permissions_denied_qr_code) diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt index 4568878446..5611e79b40 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragment.kt @@ -17,9 +17,11 @@ package im.vector.app.features.userdirectory import android.os.Bundle +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import android.widget.ScrollView import androidx.core.view.forEach import androidx.core.view.isVisible @@ -37,8 +39,10 @@ import im.vector.app.core.extensions.setupAsSearch import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.startSharePlainTextIntent +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentUserListBinding import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel -import kotlinx.android.synthetic.main.fragment_user_list.* + import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.user.model.User import javax.inject.Inject @@ -47,29 +51,32 @@ class UserListFragment @Inject constructor( private val userListController: UserListController, private val dimensionConverter: DimensionConverter, val homeServerCapabilitiesViewModelFactory: HomeServerCapabilitiesViewModel.Factory -) : VectorBaseFragment(), UserListController.Callback { +) : VectorBaseFragment(), + UserListController.Callback { private val args: UserListFragmentArgs by args() private val viewModel: UserListViewModel by activityViewModel() private val homeServerCapabilitiesViewModel: HomeServerCapabilitiesViewModel by fragmentViewModel() private lateinit var sharedActionViewModel: UserListSharedActionViewModel - override fun getLayoutResId() = R.layout.fragment_user_list + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentUserListBinding { + return FragmentUserListBinding.inflate(inflater, container, false) + } override fun getMenuRes() = args.menuResId override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) sharedActionViewModel = activityViewModelProvider.get(UserListSharedActionViewModel::class.java) - userListTitle.text = args.title - vectorBaseActivity.setSupportActionBar(userListToolbar) + views.userListTitle.text = args.title + vectorBaseActivity.setSupportActionBar(views.userListToolbar) setupRecyclerView() setupSearchView() setupCloseView() homeServerCapabilitiesViewModel.subscribe { - userListE2EbyDefaultDisabled.isVisible = !it.isE2EByDefault + views.userListE2EbyDefaultDisabled.isVisible = !it.isE2EByDefault } viewModel.selectSubscribe(this, UserListViewState::pendingInvitees) { @@ -93,7 +100,7 @@ class UserListFragment @Inject constructor( } override fun onDestroyView() { - userListRecyclerView.cleanup() + views.userListRecyclerView.cleanup() super.onDestroyView() } @@ -115,16 +122,16 @@ class UserListFragment @Inject constructor( private fun setupRecyclerView() { userListController.callback = this // Don't activate animation as we might have way to much item animation when filtering - userListRecyclerView.configureWith(userListController, disableItemAnimation = true) + views.userListRecyclerView.configureWith(userListController, disableItemAnimation = true) } private fun setupSearchView() { withState(viewModel) { - userListSearch.hint = getString(R.string.user_directory_search_hint) + views.userListSearch.hint = getString(R.string.user_directory_search_hint) } - userListSearch + views.userListSearch .textChanges() - .startWith(userListSearch.text) + .startWith(views.userListSearch.text) .subscribe { text -> val searchValue = text.trim() val action = if (searchValue.isBlank()) { @@ -136,12 +143,12 @@ class UserListFragment @Inject constructor( } .disposeOnDestroyView() - userListSearch.setupAsSearch() - userListSearch.requestFocus() + views.userListSearch.setupAsSearch() + views.userListSearch.requestFocus() } private fun setupCloseView() { - userListClose.debouncedClicks { + views.userListClose.debouncedClicks { requireActivity().finish() } } @@ -153,16 +160,16 @@ class UserListFragment @Inject constructor( private fun renderSelectedUsers(invitees: Set) { invalidateOptionsMenu() - val currentNumberOfChips = chipGroup.childCount + val currentNumberOfChips = views.chipGroup.childCount val newNumberOfChips = invitees.size - chipGroup.removeAllViews() + views.chipGroup.removeAllViews() invitees.forEach { addChipToGroup(it) } // Scroll to the bottom when adding chips. When removing chips, do not scroll if (newNumberOfChips >= currentNumberOfChips) { - chipGroupScrollView.post { - chipGroupScrollView.fullScroll(ScrollView.FOCUS_DOWN) + views.chipGroupScrollView.post { + views.chipGroupScrollView.fullScroll(ScrollView.FOCUS_DOWN) } } } @@ -175,7 +182,7 @@ class UserListFragment @Inject constructor( chip.isClickable = true chip.isCheckable = false chip.isCloseIconVisible = true - chipGroup.addView(chip) + views.chipGroup.addView(chip) chip.setOnCloseIconClickListener { viewModel.handle(UserListAction.RemovePendingInvitee(pendingInvitee)) } diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragmentArgs.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragmentArgs.kt index 041f29a77a..02fd13b39b 100644 --- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragmentArgs.kt +++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListFragmentArgs.kt @@ -17,7 +17,7 @@ package im.vector.app.features.userdirectory import android.os.Parcelable -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize @Parcelize data class UserListFragmentArgs( diff --git a/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt b/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt index 17e6fa4202..bd1935b972 100644 --- a/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt +++ b/vector/src/main/java/im/vector/app/features/webview/ConsentWebViewEventListener.kt @@ -29,12 +29,12 @@ private const val RIOT_BOT_ID = "@riot-bot:matrix.org" * This class is the Consent implementation of WebViewEventListener. * It is used to manage the consent agreement flow. */ -class ConsentWebViewEventListener(activity: VectorBaseActivity, +class ConsentWebViewEventListener(activity: VectorBaseActivity<*>, private val session: Session, private val delegate: WebViewEventListener) : WebViewEventListener by delegate { - private val safeActivity: VectorBaseActivity? by weak(activity) + private val safeActivity: VectorBaseActivity<*>? by weak(activity) override fun onPageFinished(url: String) { delegate.onPageFinished(url) diff --git a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt index 5b761d1b3a..3aa848f551 100644 --- a/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt +++ b/vector/src/main/java/im/vector/app/features/webview/VectorWebViewActivity.kt @@ -24,7 +24,9 @@ import androidx.annotation.CallSuper import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.platform.VectorBaseActivity -import kotlinx.android.synthetic.main.activity_vector_web_view.* +import im.vector.app.databinding.ActivitySimpleBinding +import im.vector.app.databinding.ActivityVectorWebViewBinding + import org.matrix.android.sdk.api.session.Session import javax.inject.Inject @@ -34,9 +36,9 @@ import javax.inject.Inject * It relies on the VectorWebViewClient * This class shouldn't be extended. To add new behaviors, you might create a new WebViewMode and a new WebViewEventListener */ -class VectorWebViewActivity : VectorBaseActivity() { +class VectorWebViewActivity : VectorBaseActivity() { - override fun getLayoutRes() = R.layout.activity_vector_web_view + override fun getBinding() = ActivityVectorWebViewBinding.inflate(layoutInflater) @Inject lateinit var session: Session @@ -46,10 +48,10 @@ class VectorWebViewActivity : VectorBaseActivity() { } override fun initUiAndData() { - configureToolbar(webview_toolbar) + configureToolbar(views.webviewToolbar) waitingView = findViewById(R.id.simple_webview_loader) - simple_webview.settings.apply { + views.simpleWebview.settings.apply { // Enable Javascript javaScriptEnabled = true @@ -70,7 +72,7 @@ class VectorWebViewActivity : VectorBaseActivity() { } val cookieManager = android.webkit.CookieManager.getInstance() - cookieManager.setAcceptThirdPartyCookies(simple_webview, true) + cookieManager.setAcceptThirdPartyCookies(views.simpleWebview, true) val url = intent.extras?.getString(EXTRA_URL) val title = intent.extras?.getString(EXTRA_TITLE, USE_TITLE_FROM_WEB_PAGE) @@ -80,15 +82,15 @@ class VectorWebViewActivity : VectorBaseActivity() { val webViewMode = intent.extras?.getSerializable(EXTRA_MODE) as WebViewMode val eventListener = webViewMode.eventListener(this, session) - simple_webview.webViewClient = VectorWebViewClient(eventListener) - simple_webview.webChromeClient = object : WebChromeClient() { + views.simpleWebview.webViewClient = VectorWebViewClient(eventListener) + views.simpleWebview.webChromeClient = object : WebChromeClient() { override fun onReceivedTitle(view: WebView, title: String) { if (title == USE_TITLE_FROM_WEB_PAGE) { setTitle(title) } } } - simple_webview.loadUrl(url) + views.simpleWebview.loadUrl(url) } /* ========================================================================================== @@ -96,8 +98,8 @@ class VectorWebViewActivity : VectorBaseActivity() { * ========================================================================================== */ override fun onBackPressed() { - if (simple_webview.canGoBack()) { - simple_webview.goBack() + if (views.simpleWebview.canGoBack()) { + views.simpleWebview.goBack() } else { super.onBackPressed() } diff --git a/vector/src/main/java/im/vector/app/features/webview/WebViewEventListenerFactory.kt b/vector/src/main/java/im/vector/app/features/webview/WebViewEventListenerFactory.kt index 64e08852b3..5bcfbb8eec 100644 --- a/vector/src/main/java/im/vector/app/features/webview/WebViewEventListenerFactory.kt +++ b/vector/src/main/java/im/vector/app/features/webview/WebViewEventListenerFactory.kt @@ -24,5 +24,5 @@ interface WebViewEventListenerFactory { /** * @return an instance of WebViewEventListener */ - fun eventListener(activity: VectorBaseActivity, session: Session): WebViewEventListener + fun eventListener(activity: VectorBaseActivity<*>, session: Session): WebViewEventListener } diff --git a/vector/src/main/java/im/vector/app/features/webview/WebViewMode.kt b/vector/src/main/java/im/vector/app/features/webview/WebViewMode.kt index edf98f66d8..58c8270154 100644 --- a/vector/src/main/java/im/vector/app/features/webview/WebViewMode.kt +++ b/vector/src/main/java/im/vector/app/features/webview/WebViewMode.kt @@ -25,12 +25,12 @@ import org.matrix.android.sdk.api.session.Session enum class WebViewMode : WebViewEventListenerFactory { DEFAULT { - override fun eventListener(activity: VectorBaseActivity, session: Session): WebViewEventListener { + override fun eventListener(activity: VectorBaseActivity<*>, session: Session): WebViewEventListener { return DefaultWebViewEventListener() } }, CONSENT { - override fun eventListener(activity: VectorBaseActivity, session: Session): WebViewEventListener { + override fun eventListener(activity: VectorBaseActivity<*>, session: Session): WebViewEventListener { return ConsentWebViewEventListener(activity, session, DefaultWebViewEventListener()) } }; diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt index d28fc134a9..d7f5407a38 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetActivity.kt @@ -28,16 +28,21 @@ import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.addFragment import im.vector.app.core.platform.ToolbarConfigurable import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding +import im.vector.app.databinding.ActivityWidgetBinding import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewEvents import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewModel import im.vector.app.features.widgets.permissions.RoomWidgetPermissionViewState -import kotlinx.android.synthetic.main.activity_widget.* + import org.matrix.android.sdk.api.session.events.model.Content import java.io.Serializable import javax.inject.Inject -class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewModel.Factory, RoomWidgetPermissionViewModel.Factory { +class WidgetActivity : VectorBaseActivity(), + ToolbarConfigurable, + WidgetViewModel.Factory, + RoomWidgetPermissionViewModel.Factory { companion object { @@ -69,7 +74,7 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode private val viewModel: WidgetViewModel by viewModel() private val permissionViewModel: RoomWidgetPermissionViewModel by viewModel() - override fun getLayoutRes() = R.layout.activity_widget + override fun getBinding() = ActivityWidgetBinding.inflate(layoutInflater) override fun getMenuRes() = R.menu.menu_widget @@ -85,8 +90,8 @@ class WidgetActivity : VectorBaseActivity(), ToolbarConfigurable, WidgetViewMode finish() return } - configure(toolbar) - toolbar.isVisible = widgetArgs.kind.nameRes != 0 + configure(views.toolbar) + views.toolbar.isVisible = widgetArgs.kind.nameRes != 0 viewModel.observeViewEvents { when (it) { is WidgetViewEvents.Close -> handleClose(it) diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt index 35d7867db3..45e682b1ce 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetFragment.kt @@ -21,9 +21,11 @@ import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.os.Parcelable +import android.view.LayoutInflater import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import androidx.appcompat.app.AlertDialog import androidx.core.view.isInvisible import androidx.core.view.isVisible @@ -40,11 +42,13 @@ import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.openUrlInExternalBrowser +import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.databinding.FragmentRoomWidgetBinding import im.vector.app.features.webview.WebViewEventListener import im.vector.app.features.widgets.webview.clearAfterWidget import im.vector.app.features.widgets.webview.setupForWidget -import kotlinx.android.parcel.Parcelize -import kotlinx.android.synthetic.main.fragment_room_widget.* +import kotlinx.parcelize.Parcelize + import org.matrix.android.sdk.api.session.terms.TermsService import timber.log.Timber import java.net.URISyntaxException @@ -59,12 +63,17 @@ data class WidgetArgs( val urlParams: Map = emptyMap() ) : Parcelable -class WidgetFragment @Inject constructor() : VectorBaseFragment(), WebViewEventListener, OnBackPressed { +class WidgetFragment @Inject constructor() : + VectorBaseFragment(), + WebViewEventListener, + OnBackPressed { private val fragmentArgs: WidgetArgs by args() private val viewModel: WidgetViewModel by activityViewModel() - override fun getLayoutResId() = R.layout.fragment_room_widget + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomWidgetBinding { + return FragmentRoomWidgetBinding.inflate(inflater, container, false) + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt index e1840fe687..2eef26e775 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/permissions/RoomWidgetPermissionBottomSheet.kt @@ -20,7 +20,9 @@ import android.os.Bundle import android.text.Spannable import android.text.SpannableStringBuilder import android.text.style.BulletSpan +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState @@ -28,15 +30,20 @@ import im.vector.app.R import im.vector.app.core.di.ScreenComponent import im.vector.app.core.extensions.withArgs import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetRoomWidgetPermissionBinding import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.widgets.WidgetArgs -import kotlinx.android.synthetic.main.bottom_sheet_room_widget_permission.* + import org.matrix.android.sdk.api.util.toMatrixItem import javax.inject.Inject -class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() { +class RoomWidgetPermissionBottomSheet : + VectorBaseBottomSheetDialogFragment() { - override fun getLayoutResId(): Int = R.layout.bottom_sheet_room_widget_permission + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetRoomWidgetPermissionBinding { + return BottomSheetRoomWidgetPermissionBinding.inflate(inflater, container, false) + } private val viewModel: RoomWidgetPermissionViewModel by activityViewModel() @@ -58,17 +65,17 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() { } private fun setupViews() { - widgetPermissionDecline.setOnClickListener { doDecline() } - widgetPermissionContinue.setOnClickListener { doAccept() } + views.widgetPermissionDecline.setOnClickListener { doDecline() } + views.widgetPermissionContinue.setOnClickListener { doAccept() } } override fun invalidate() = withState(viewModel) { state -> super.invalidate() val permissionData = state.permissionData() ?: return@withState - widgetPermissionOwnerId.text = permissionData.widget.senderInfo?.userId ?: "" - widgetPermissionOwnerDisplayName.text = permissionData.widget.senderInfo?.disambiguatedDisplayName + views.widgetPermissionOwnerId.text = permissionData.widget.senderInfo?.userId ?: "" + views.widgetPermissionOwnerDisplayName.text = permissionData.widget.senderInfo?.disambiguatedDisplayName permissionData.widget.senderInfo?.toMatrixItem()?.also { - avatarRenderer.render(it, widgetPermissionOwnerAvatar) + avatarRenderer.render(it, views.widgetPermissionOwnerAvatar) } val domain = permissionData.widgetDomain ?: "" @@ -85,7 +92,7 @@ class RoomWidgetPermissionBottomSheet : VectorBaseBottomSheetDialogFragment() { infoBuilder.append(bulletPoint, BulletSpan(resources.getDimension(R.dimen.quote_gap).toInt()), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } infoBuilder.append("\n") - widgetPermissionSharedInfo.text = infoBuilder + views.widgetPermissionSharedInfo.text = infoBuilder } private fun doDecline() { diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt index 8b014eb6a2..0c646d5d5e 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetActionButton.kt @@ -25,7 +25,7 @@ import androidx.core.view.isVisible import im.vector.app.R import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.themes.ThemeUtils -import kotlinx.android.synthetic.main.item_signout_action.view.* + class SignOutBottomSheetActionButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 diff --git a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt index 49c688c801..f7834bf1de 100644 --- a/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt +++ b/vector/src/main/java/im/vector/app/features/workers/signout/SignOutBottomSheetDialogFragment.kt @@ -19,7 +19,9 @@ package im.vector.app.features.workers.signout import android.app.Activity import android.app.Dialog import android.os.Bundle +import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.FrameLayout import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible @@ -35,17 +37,21 @@ import im.vector.app.core.dialogs.ExportKeysDialog import im.vector.app.core.extensions.queryExportKeys import im.vector.app.core.extensions.registerStartForActivityResult import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment +import im.vector.app.databinding.BottomSheetGenericListBinding +import im.vector.app.databinding.BottomSheetLogoutAndBackupBinding import im.vector.app.features.crypto.keysbackup.setup.KeysBackupSetupActivity import im.vector.app.features.crypto.recover.BootstrapBottomSheet import im.vector.app.features.crypto.recover.SetupMode -import kotlinx.android.synthetic.main.bottom_sheet_logout_and_backup.* + import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import timber.log.Timber import javax.inject.Inject // TODO this needs to be refactored to current standard and remove legacy -class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), SignoutCheckViewModel.Factory { +class SignOutBottomSheetDialogFragment : + VectorBaseBottomSheetDialogFragment(), + SignoutCheckViewModel.Factory { var onSignOut: Runnable? = null @@ -78,11 +84,11 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setupRecoveryButton.action = { + views.setupRecoveryButton.action = { BootstrapBottomSheet.show(parentFragmentManager, SetupMode.NORMAL) } - exitAnywayButton.action = { + views.exitAnywayButton.action = { context?.let { AlertDialog.Builder(it) .setTitle(R.string.are_you_sure) @@ -95,17 +101,17 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), } } - signOutButton.action = { + views.signOutButton.action = { onSignOut?.run() } - exportManuallyButton.action = { + views.exportManuallyButton.action = { withState(viewModel) { state -> queryExportKeys(state.userId, manualExportKeysActivityResultLauncher) } } - setupMegolmBackupButton.action = { + views.setupMegolmBackupButton.action = { setupBackupActivityResultLauncher.launch(KeysBackupSetupActivity.intent(requireContext(), true)) } @@ -136,80 +142,80 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), } override fun invalidate() = withState(viewModel) { state -> - signoutExportingLoading.isVisible = false + views.signoutExportingLoading.isVisible = false if (state.crossSigningSetupAllKeysKnown && !state.backupIsSetup) { - bottom_sheet_signout_warning_text.text = getString(R.string.sign_out_bottom_sheet_warning_no_backup) - backingUpStatusGroup.isVisible = false + views.bottomSheetSignoutWarningText.text = getString(R.string.sign_out_bottom_sheet_warning_no_backup) + views.backingUpStatusGroup.isVisible = false // we should show option to setup 4S - setupRecoveryButton.isVisible = true - setupMegolmBackupButton.isVisible = false + views.setupRecoveryButton.isVisible = true + views.setupMegolmBackupButton.isVisible = false // We let the option to ignore and quit - exportManuallyButton.isVisible = true - exitAnywayButton.isVisible = true - signOutButton.isVisible = false + views.exportManuallyButton.isVisible = true + views.exitAnywayButton.isVisible = true + views.signOutButton.isVisible = false } else if (state.keysBackupState == KeysBackupState.Unknown || state.keysBackupState == KeysBackupState.Disabled) { - bottom_sheet_signout_warning_text.text = getString(R.string.sign_out_bottom_sheet_warning_no_backup) - backingUpStatusGroup.isVisible = false + views.bottomSheetSignoutWarningText.text = getString(R.string.sign_out_bottom_sheet_warning_no_backup) + views.backingUpStatusGroup.isVisible = false // no key backup and cannot setup full 4S // we propose to setup // we should show option to setup 4S - setupRecoveryButton.isVisible = false - setupMegolmBackupButton.isVisible = true + views.setupRecoveryButton.isVisible = false + views.setupMegolmBackupButton.isVisible = true // We let the option to ignore and quit - exportManuallyButton.isVisible = true - exitAnywayButton.isVisible = true - signOutButton.isVisible = false + views.exportManuallyButton.isVisible = true + views.exitAnywayButton.isVisible = true + views.signOutButton.isVisible = false } else { // so keybackup is setup // You should wait until all are uploaded - setupRecoveryButton.isVisible = false + views.setupRecoveryButton.isVisible = false when (state.keysBackupState) { KeysBackupState.ReadyToBackUp -> { - bottom_sheet_signout_warning_text.text = getString(R.string.action_sign_out_confirmation_simple) + views.bottomSheetSignoutWarningText.text = getString(R.string.action_sign_out_confirmation_simple) // Ok all keys are backedUp - backingUpStatusGroup.isVisible = true - backupProgress.isVisible = false - backupCompleteImage.isVisible = true - backupStatusText.text = getString(R.string.keys_backup_info_keys_all_backup_up) + views.backingUpStatusGroup.isVisible = true + views.backupProgress.isVisible = false + views.backupCompleteImage.isVisible = true + views.backupStatusText.text = getString(R.string.keys_backup_info_keys_all_backup_up) - setupMegolmBackupButton.isVisible = false - exportManuallyButton.isVisible = false - exitAnywayButton.isVisible = false + views.setupMegolmBackupButton.isVisible = false + views.exportManuallyButton.isVisible = false + views.exitAnywayButton.isVisible = false // You can signout - signOutButton.isVisible = true + views.signOutButton.isVisible = true } KeysBackupState.WillBackUp, KeysBackupState.BackingUp -> { - bottom_sheet_signout_warning_text.text = getString(R.string.sign_out_bottom_sheet_warning_backing_up) + views.bottomSheetSignoutWarningText.text = getString(R.string.sign_out_bottom_sheet_warning_backing_up) // save in progress - backingUpStatusGroup.isVisible = true - backupProgress.isVisible = true - backupCompleteImage.isVisible = false - backupStatusText.text = getString(R.string.sign_out_bottom_sheet_backing_up_keys) + views.backingUpStatusGroup.isVisible = true + views.backupProgress.isVisible = true + views.backupCompleteImage.isVisible = false + views.backupStatusText.text = getString(R.string.sign_out_bottom_sheet_backing_up_keys) - setupMegolmBackupButton.isVisible = false - exportManuallyButton.isVisible = false - exitAnywayButton.isVisible = true - signOutButton.isVisible = false + views.setupMegolmBackupButton.isVisible = false + views.exportManuallyButton.isVisible = false + views.exitAnywayButton.isVisible = true + views.signOutButton.isVisible = false } KeysBackupState.NotTrusted -> { - bottom_sheet_signout_warning_text.text = getString(R.string.sign_out_bottom_sheet_warning_backup_not_active) + views.bottomSheetSignoutWarningText.text = getString(R.string.sign_out_bottom_sheet_warning_backup_not_active) // It's not trusted and we know there are unsaved keys.. - backingUpStatusGroup.isVisible = false + views.backingUpStatusGroup.isVisible = false // option to enter pass/key - setupMegolmBackupButton.isVisible = true - exportManuallyButton.isVisible = true - exitAnywayButton.isVisible = true - signOutButton.isVisible = false + views.setupMegolmBackupButton.isVisible = true + views.exportManuallyButton.isVisible = true + views.exitAnywayButton.isVisible = true + views.signOutButton.isVisible = false } else -> { // mmm.. strange state - exitAnywayButton.isVisible = true + views.exitAnywayButton.isVisible = true } } } @@ -217,25 +223,25 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), // final call if keys have been exported when (state.hasBeenExportedToFile) { is Loading -> { - signoutExportingLoading.isVisible = true - backingUpStatusGroup.isVisible = false + views.signoutExportingLoading.isVisible = true + views.backingUpStatusGroup.isVisible = false - setupRecoveryButton.isVisible = false - setupMegolmBackupButton.isVisible = false - exportManuallyButton.isVisible = false - exitAnywayButton.isVisible = true - signOutButton.isVisible = false + views.setupRecoveryButton.isVisible = false + views.setupMegolmBackupButton.isVisible = false + views.exportManuallyButton.isVisible = false + views.exitAnywayButton.isVisible = true + views.signOutButton.isVisible = false } is Success -> { if (state.hasBeenExportedToFile.invoke()) { - bottom_sheet_signout_warning_text.text = getString(R.string.action_sign_out_confirmation_simple) - backingUpStatusGroup.isVisible = false + views.bottomSheetSignoutWarningText.text = getString(R.string.action_sign_out_confirmation_simple) + views.backingUpStatusGroup.isVisible = false - setupRecoveryButton.isVisible = false - setupMegolmBackupButton.isVisible = false - exportManuallyButton.isVisible = false - exitAnywayButton.isVisible = false - signOutButton.isVisible = true + views.setupRecoveryButton.isVisible = false + views.setupMegolmBackupButton.isVisible = false + views.exportManuallyButton.isVisible = false + views.exitAnywayButton.isVisible = false + views.signOutButton.isVisible = true } } else -> { @@ -244,7 +250,9 @@ class SignOutBottomSheetDialogFragment : VectorBaseBottomSheetDialogFragment(), super.invalidate() } - override fun getLayoutResId() = R.layout.bottom_sheet_logout_and_backup + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetLogoutAndBackupBinding { + return BottomSheetLogoutAndBackupBinding.inflate(inflater, container, false) + } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) diff --git a/vector/src/main/res/layout/activity.xml b/vector/src/main/res/layout/activity.xml index e5f6655263..3e8adbbd35 100644 --- a/vector/src/main/res/layout/activity.xml +++ b/vector/src/main/res/layout/activity.xml @@ -26,7 +26,9 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/toolbar" /> - + \ No newline at end of file diff --git a/vector/src/main/res/layout/activity_home.xml b/vector/src/main/res/layout/activity_home.xml index f8496f4116..50fc11500a 100644 --- a/vector/src/main/res/layout/activity_home.xml +++ b/vector/src/main/res/layout/activity_home.xml @@ -16,7 +16,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - + diff --git a/vector/src/main/res/layout/activity_room_detail.xml b/vector/src/main/res/layout/activity_room_detail.xml index 4139aa12dc..aca4ee4e63 100644 --- a/vector/src/main/res/layout/activity_room_detail.xml +++ b/vector/src/main/res/layout/activity_room_detail.xml @@ -20,7 +20,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" /> - + diff --git a/vector/src/main/res/layout/fragment_create_room.xml b/vector/src/main/res/layout/fragment_create_room.xml index 3abcafc94d..b4f318ae76 100644 --- a/vector/src/main/res/layout/fragment_create_room.xml +++ b/vector/src/main/res/layout/fragment_create_room.xml @@ -67,7 +67,9 @@ - + diff --git a/vector/src/main/res/layout/fragment_generic_recycler.xml b/vector/src/main/res/layout/fragment_generic_recycler.xml index 4aded532e8..6ddbc5baab 100644 --- a/vector/src/main/res/layout/fragment_generic_recycler.xml +++ b/vector/src/main/res/layout/fragment_generic_recycler.xml @@ -13,6 +13,8 @@ app:itemSpacing="1dp" tools:listitem="@layout/item_pushgateway" /> - + diff --git a/vector/src/main/res/layout/fragment_matrix_profile.xml b/vector/src/main/res/layout/fragment_matrix_profile.xml index 288cbe82d4..c380ea293c 100644 --- a/vector/src/main/res/layout/fragment_matrix_profile.xml +++ b/vector/src/main/res/layout/fragment_matrix_profile.xml @@ -104,6 +104,8 @@ app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:listitem="@layout/item_profile_action" /> - + \ No newline at end of file diff --git a/vector/src/main/res/layout/fragment_room_setting_generic.xml b/vector/src/main/res/layout/fragment_room_setting_generic.xml index 7ff63f3ce5..47650481e4 100644 --- a/vector/src/main/res/layout/fragment_room_setting_generic.xml +++ b/vector/src/main/res/layout/fragment_room_setting_generic.xml @@ -101,6 +101,8 @@ - +