diff --git a/.github/workflows/triage-priority-bugs.yml b/.github/workflows/triage-priority-bugs.yml index 6cde154370..e762102226 100644 --- a/.github/workflows/triage-priority-bugs.yml +++ b/.github/workflows/triage-priority-bugs.yml @@ -27,7 +27,7 @@ jobs: - uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488 with: project: Android App Team - column: P1 + column: Important Issues & Topics (P1) repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }} P1_issues_to_crypto_team_workboard: diff --git a/build.gradle b/build.gradle index 71875c49f1..a40790d441 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ plugins { id "io.gitlab.arturbosch.detekt" version "1.21.0" // Dependency Analysis - id 'com.autonomousapps.dependency-analysis' version "1.12.0" + id 'com.autonomousapps.dependency-analysis' version "1.13.1" } // https://github.com/jeremylong/DependencyCheck diff --git a/changelog.d/7039.wip b/changelog.d/7039.wip new file mode 100644 index 0000000000..5059029a0e --- /dev/null +++ b/changelog.d/7039.wip @@ -0,0 +1 @@ +[New Layout] Changes space icon in fab and in release notes screen diff --git a/changelog.d/7054.bugfix b/changelog.d/7054.bugfix new file mode 100644 index 0000000000..9cfda8ebe3 --- /dev/null +++ b/changelog.d/7054.bugfix @@ -0,0 +1 @@ +Fix invite to room when in a space buttons not working. diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt b/vector-app/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt index 9434006060..ad11d953d4 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt @@ -101,11 +101,11 @@ class UiAllScreensSanityTest { val spaceName = UUID.randomUUID().toString() elementRobot.space { - createSpace { + createSpace(true) { createAndCrawl(spaceName) } val publicSpaceName = UUID.randomUUID().toString() - createSpace { + createSpace(false) { createPublicSpace(publicSpaceName) } diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt index 2e87a85e59..48a435c877 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/ElementRobot.kt @@ -51,8 +51,7 @@ import im.vector.app.withIdlingResource import timber.log.Timber class ElementRobot { - - var features: VectorFeatures = DefaultVectorFeatures() + private val features: VectorFeatures = DefaultVectorFeatures() fun onboarding(block: OnboardingRobot.() -> Unit) { block(OnboardingRobot()) @@ -84,33 +83,56 @@ class ElementRobot { } fun settings(shouldGoBack: Boolean = true, block: SettingsRobot.() -> Unit) { - openDrawer() - clickOn(R.id.homeDrawerHeaderSettingsView) + if (features.isNewAppLayoutEnabled()) { + onView(withId((R.id.avatar))).perform(click()) + } else { + openDrawer() + clickOn(R.id.homeDrawerHeaderSettingsView) + } + block(SettingsRobot()) if (shouldGoBack) pressBack() waitUntilViewVisible(withId(R.id.roomListContainer)) } fun newDirectMessage(block: NewDirectMessageRobot.() -> Unit) { - clickOn(R.id.bottom_action_people) - clickOn(R.id.createChatRoomButton) + if (features.isNewAppLayoutEnabled()) { + clickOn(R.id.newLayoutCreateChatButton) + waitUntilDialogVisible(withId(R.id.start_chat)) + clickOn(R.id.start_chat) + } else { + clickOn(R.id.bottom_action_people) + clickOn(R.id.createChatRoomButton) + } + waitUntilActivityVisible { waitUntilViewVisible(withId(R.id.userListSearch)) } closeSoftKeyboard() block(NewDirectMessageRobot()) pressBack() + if (features.isNewAppLayoutEnabled()) { + pressBack() // close create dialog + } waitUntilViewVisible(withId(R.id.roomListContainer)) } fun newRoom(block: NewRoomRobot.() -> Unit) { - clickOn(R.id.bottom_action_rooms) + if (!features.isNewAppLayoutEnabled()) { + clickOn(R.id.bottom_action_rooms) + } RoomListRobot().newRoom { block() } + if (features.isNewAppLayoutEnabled()) { + pressBack() // close create dialog + } waitUntilViewVisible(withId(R.id.roomListContainer)) } fun roomList(block: RoomListRobot.() -> Unit) { - clickOn(R.id.bottom_action_rooms) + if (!features.isNewAppLayoutEnabled()) { + clickOn(R.id.bottom_action_rooms) + } + block(RoomListRobot()) waitUntilViewVisible(withId(R.id.roomListContainer)) } diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/NewRoomRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/NewRoomRobot.kt index 09ff1162c0..3d82fa4a65 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/NewRoomRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/NewRoomRobot.kt @@ -21,13 +21,18 @@ import androidx.test.espresso.matcher.ViewMatchers.withId import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import im.vector.app.R import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.DefaultVectorFeatures +import im.vector.app.features.VectorFeatures class NewRoomRobot( var createdRoom: Boolean = false ) { + private val features: VectorFeatures = DefaultVectorFeatures() fun createNewRoom(block: CreateNewRoomRobot.() -> Unit) { - clickOn(R.string.create_new_room) + if (features.isNewAppLayoutEnabled()) { + clickOn(R.string.create_new_room) + } waitUntilViewVisible(withId(R.id.createRoomForm)) val createNewRoomRobot = CreateNewRoomRobot() block(createNewRoomRobot) diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt index e72535c116..1f1a799db3 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/OnboardingRobot.kt @@ -33,7 +33,6 @@ import im.vector.app.features.DefaultVectorFeatures import im.vector.app.waitForView class OnboardingRobot { - private val defaultVectorFeatures = DefaultVectorFeatures() fun crawl() { diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/RoomListRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/RoomListRobot.kt index dc07f06202..71ccad0870 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/RoomListRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/RoomListRobot.kt @@ -27,9 +27,13 @@ import com.adevinta.android.barista.assertion.BaristaVisibilityAssertions import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn import im.vector.app.R import im.vector.app.espresso.tools.waitUntilActivityVisible +import im.vector.app.espresso.tools.waitUntilDialogVisible +import im.vector.app.features.DefaultVectorFeatures +import im.vector.app.features.VectorFeatures import im.vector.app.features.roomdirectory.RoomDirectoryActivity class RoomListRobot { + private val features: VectorFeatures = DefaultVectorFeatures() fun openRoom(roomName: String, block: RoomDetailRobot.() -> Unit) { clickOn(roomName) @@ -49,9 +53,15 @@ class RoomListRobot { } fun newRoom(block: NewRoomRobot.() -> Unit) { - clickOn(R.id.createGroupRoomButton) - waitUntilActivityVisible { - BaristaVisibilityAssertions.assertDisplayed(R.id.publicRoomsList) + if (features.isNewAppLayoutEnabled()) { + clickOn(R.id.newLayoutCreateChatButton) + waitUntilDialogVisible(ViewMatchers.withId(R.id.create_room)) + clickOn(R.id.create_room) + } else { + clickOn(R.id.createGroupRoomButton) + waitUntilActivityVisible { + BaristaVisibilityAssertions.assertDisplayed(R.id.publicRoomsList) + } } val newRoomRobot = NewRoomRobot() block(newRoomRobot) diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt index 018f3097ba..e5147c2085 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceCreateRobot.kt @@ -31,6 +31,7 @@ import im.vector.app.espresso.tools.waitUntilActivityVisible import im.vector.app.espresso.tools.waitUntilDialogVisible import im.vector.app.espresso.tools.waitUntilViewVisible import im.vector.app.features.home.HomeActivity +import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.spaces.manage.SpaceManageActivity class SpaceCreateRobot { @@ -85,7 +86,9 @@ class SpaceCreateRobot { clickOn(R.id.nextButton) waitUntilViewVisible(withId(R.id.recyclerView)) clickOn(R.id.nextButton) - waitUntilDialogVisible(withId(R.id.inviteByMxidButton)) + waitUntilActivityVisible { + waitUntilDialogVisible(withId(R.id.inviteByMxidButton)) + } // close invite dialog pressBack() waitUntilViewVisible(withId(R.id.timelineRecyclerView)) diff --git a/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt b/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt index b8a2f4313b..8b69b43107 100644 --- a/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt +++ b/vector-app/src/androidTest/java/im/vector/app/ui/robot/space/SpaceRobot.kt @@ -18,6 +18,8 @@ package im.vector.app.ui.robot.space import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.Espresso +import androidx.test.espresso.action.ViewActions.click +import androidx.test.espresso.action.ViewActions.longClick import androidx.test.espresso.contrib.RecyclerViewActions import androidx.test.espresso.matcher.ViewMatchers import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn @@ -26,18 +28,43 @@ import com.adevinta.android.barista.internal.viewaction.ClickChildAction import im.vector.app.R import im.vector.app.espresso.tools.waitUntilDialogVisible import im.vector.app.espresso.tools.waitUntilViewVisible +import im.vector.app.features.DefaultVectorFeatures +import im.vector.app.features.VectorFeatures import org.hamcrest.Matchers class SpaceRobot { + private val features: VectorFeatures = DefaultVectorFeatures() - fun createSpace(block: SpaceCreateRobot.() -> Unit) { - openDrawer() - clickOn(R.string.create_space) + fun createSpace(isFirstSpace: Boolean, block: SpaceCreateRobot.() -> Unit) { + if (features.isNewAppLayoutEnabled()) { + clickOn(R.id.newLayoutOpenSpacesButton) + if (isFirstSpace) { + waitUntilDialogVisible(ViewMatchers.withId(R.id.spaces_empty_group)) + clickOn(R.id.spaces_empty_button) + } else { + waitUntilDialogVisible(ViewMatchers.withId(R.id.groupListView)) + Espresso.onView(ViewMatchers.withId(R.id.groupListView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(ViewMatchers.withId(R.id.plus)), + click() + ).atPosition(0) + ) + } + } else { + openDrawer() + clickOn(R.string.create_space) + } block(SpaceCreateRobot()) } fun spaceMenu(spaceName: String, block: SpaceMenuRobot.() -> Unit) { - openDrawer() + if (features.isNewAppLayoutEnabled()) { + clickOn(R.id.newLayoutOpenSpacesButton) + waitUntilDialogVisible(ViewMatchers.withId(R.id.groupListView)) + } else { + openDrawer() + } with(SpaceMenuRobot()) { openMenu(spaceName) block() @@ -46,19 +73,32 @@ class SpaceRobot { fun openMenu(spaceName: String) { waitUntilViewVisible(ViewMatchers.withId(R.id.groupListView)) - Espresso.onView(ViewMatchers.withId(R.id.groupListView)) - .perform( - RecyclerViewActions.actionOnItem( - ViewMatchers.hasDescendant(Matchers.allOf(ViewMatchers.withId(R.id.groupNameView), ViewMatchers.withText(spaceName))), - ClickChildAction.clickChildWithId(R.id.groupTmpLeave) - ).atPosition(0) - ) + if (features.isNewAppLayoutEnabled()) { + Espresso.onView(ViewMatchers.withId(R.id.groupListView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(Matchers.allOf(ViewMatchers.withId(R.id.name), ViewMatchers.withText(spaceName))), + longClick() + ).atPosition(0) + ) + } else { + Espresso.onView(ViewMatchers.withId(R.id.groupListView)) + .perform( + RecyclerViewActions.actionOnItem( + ViewMatchers.hasDescendant(Matchers.allOf(ViewMatchers.withId(R.id.groupNameView), ViewMatchers.withText(spaceName))), + ClickChildAction.clickChildWithId(R.id.groupTmpLeave) + ).atPosition(0) + ) + } + waitUntilDialogVisible(ViewMatchers.withId(R.id.spaceNameView)) } fun selectSpace(spaceName: String) { - openDrawer() - waitUntilViewVisible(ViewMatchers.withId(R.id.groupListView)) + if (!features.isNewAppLayoutEnabled()) { + openDrawer() + waitUntilViewVisible(ViewMatchers.withId(R.id.groupListView)) + } clickOn(spaceName) } } 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 58ff881b7d..8a624b23d9 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 @@ -378,7 +378,7 @@ class HomeActivity : lifecycleScope.launch { val isHandled = permalinkHandler.launch( - context = this@HomeActivity, + fragmentActivity = this@HomeActivity, deepLink = resolvedLink, navigationInterceptor = this@HomeActivity, buildTask = true 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 5141923e65..8eab759fcd 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 @@ -232,9 +232,10 @@ class HomeDetailFragment : viewBinder = VerificationVectorAlert.ViewBinder(user, avatarRenderer) colorInt = colorProvider.getColorFromAttribute(R.attr.colorPrimary) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity<*>) - ?.navigator - ?.requestSessionVerification(requireContext(), newest.deviceId ?: "") + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { vectorBaseActivity -> + vectorBaseActivity.navigator + .requestSessionVerification(vectorBaseActivity, newest.deviceId ?: "") + } unknownDeviceDetectorSharedViewModel.handle( UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(newest.deviceId?.let { listOf(it) }.orEmpty()) ) diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt index 12dee92430..3681ba4c15 100644 --- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt @@ -250,9 +250,10 @@ class NewHomeDetailFragment : viewBinder = VerificationVectorAlert.ViewBinder(user, avatarRenderer) colorInt = colorProvider.getColorFromAttribute(R.attr.colorPrimary) contentAction = Runnable { - (weakCurrentActivity?.get() as? VectorBaseActivity<*>) - ?.navigator - ?.requestSessionVerification(requireContext(), newest.deviceId ?: "") + (weakCurrentActivity?.get() as? VectorBaseActivity<*>)?.let { vectorBaseActivity -> + vectorBaseActivity.navigator + .requestSessionVerification(vectorBaseActivity, newest.deviceId ?: "") + } unknownDeviceDetectorSharedViewModel.handle( UnknownDeviceDetectorSharedViewModel.Action.IgnoreDevice(newest.deviceId?.let { listOf(it) }.orEmpty()) ) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 350748097c..8b6429abb1 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -497,7 +497,7 @@ class TimelineFragment : RoomDetailViewEvents.HideWaitingView -> vectorBaseActivity.hideWaitingView() is RoomDetailViewEvents.RequestNativeWidgetPermission -> requestNativeWidgetPermission(it) is RoomDetailViewEvents.OpenRoom -> handleOpenRoom(it) - RoomDetailViewEvents.OpenInvitePeople -> navigator.openInviteUsersToRoom(requireContext(), timelineArgs.roomId) + RoomDetailViewEvents.OpenInvitePeople -> navigator.openInviteUsersToRoom(requireActivity(), timelineArgs.roomId) RoomDetailViewEvents.OpenSetRoomAvatarDialog -> galleryOrCameraDialogHelper.show() RoomDetailViewEvents.OpenRoomSettings -> handleOpenRoomSettings(RoomProfileActivity.EXTRA_DIRECT_ACCESS_ROOM_SETTINGS) RoomDetailViewEvents.OpenRoomProfile -> handleOpenRoomSettings() @@ -2190,7 +2190,7 @@ class TimelineFragment : override fun onRoomCreateLinkClicked(url: String) { viewLifecycleOwner.lifecycleScope.launchWhenResumed { permalinkHandler - .launch(requireContext(), url, object : NavigationInterceptor { + .launch(requireActivity(), url, object : NavigationInterceptor { override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?, rootThreadEventId: String?): Boolean { requireActivity().finish() return false 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 de51101804..2c876273ea 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 @@ -188,7 +188,7 @@ class RoomListFragment : } private fun handleShowMxToLink(link: String) { - navigator.openMatrixToBottomSheet(requireContext(), link, OriginOfMatrixTo.ROOM_LIST) + navigator.openMatrixToBottomSheet(requireActivity(), link, OriginOfMatrixTo.ROOM_LIST) } override fun onDestroyView() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/recent/RecentRoomCarouselController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/recent/RecentRoomCarouselController.kt index 0c5d9a3533..df5ce28da5 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/home/recent/RecentRoomCarouselController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/recent/RecentRoomCarouselController.kt @@ -41,7 +41,7 @@ class RecentRoomCarouselController @Inject constructor( private val hPadding = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, - 16f, + 4f, resources.displayMetrics ).toInt() @@ -51,12 +51,6 @@ class RecentRoomCarouselController @Inject constructor( resources.displayMetrics ).toInt() - private val itemSpacing = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, - 24f, - resources.displayMetrics - ).toInt() - fun submitList(recentList: List) { this.data = recentList requestModelBuild() @@ -72,7 +66,8 @@ class RecentRoomCarouselController @Inject constructor( host.topPadding, host.hPadding, 0, - host.itemSpacing) + 0, + ) ) onBind { _, view, _ -> val colorSurface = MaterialColors.getColor(view, R.attr.vctr_toolbar_background) diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index 3b56867a20..53ed307da9 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -25,11 +25,11 @@ import android.view.View import android.view.Window import android.widget.Toast import androidx.activity.result.ActivityResultLauncher -import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityOptionsCompat import androidx.core.app.TaskStackBuilder import androidx.core.util.Pair import androidx.core.view.ViewCompat +import androidx.fragment.app.FragmentActivity import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.SpaceStateHandler @@ -224,75 +224,65 @@ class DefaultNavigator @Inject constructor( startActivity(context, SpacePreviewActivity.newIntent(context, spaceId), false) } - override fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) { + override fun performDeviceVerification(fragmentActivity: FragmentActivity, otherUserId: String, sasTransactionId: String) { val session = sessionHolder.getSafeActiveSession() ?: return val tx = session.cryptoService().verificationService().getExistingTransaction(otherUserId, sasTransactionId) ?: return (tx as? IncomingSasVerificationTransaction)?.performAccept() - if (context is AppCompatActivity) { - VerificationBottomSheet.withArgs( - roomId = null, - otherUserId = otherUserId, - transactionId = sasTransactionId - ).show(context.supportFragmentManager, "REQPOP") - } + VerificationBottomSheet.withArgs( + roomId = null, + otherUserId = otherUserId, + transactionId = sasTransactionId + ).show(fragmentActivity.supportFragmentManager, "REQPOP") } - override fun requestSessionVerification(context: Context, otherSessionId: String) { + override fun requestSessionVerification(fragmentActivity: FragmentActivity, otherSessionId: String) { val session = sessionHolder.getSafeActiveSession() ?: return val pr = session.cryptoService().verificationService().requestKeyVerification( supportedVerificationMethodsProvider.provide(), session.myUserId, listOf(otherSessionId) ) - if (context is AppCompatActivity) { - VerificationBottomSheet.withArgs( - roomId = null, - otherUserId = session.myUserId, - transactionId = pr.transactionId - ).show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) - } + VerificationBottomSheet.withArgs( + roomId = null, + otherUserId = session.myUserId, + transactionId = pr.transactionId + ).show(fragmentActivity.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) } - override fun requestSelfSessionVerification(context: Context) { + override fun requestSelfSessionVerification(fragmentActivity: FragmentActivity) { val session = sessionHolder.getSafeActiveSession() ?: return val otherSessions = session.cryptoService() .getCryptoDeviceInfo(session.myUserId) .filter { it.deviceId != session.sessionParams.deviceId } .map { it.deviceId } - if (context is AppCompatActivity) { - if (otherSessions.isNotEmpty()) { - val pr = session.cryptoService().verificationService().requestKeyVerification( - supportedVerificationMethodsProvider.provide(), - session.myUserId, - otherSessions - ) - VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId) - .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) - } else { - VerificationBottomSheet.forSelfVerification(session) - .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) - } - } - } - - override fun waitSessionVerification(context: Context) { - val session = sessionHolder.getSafeActiveSession() ?: return - if (context is AppCompatActivity) { - VerificationBottomSheet.forSelfVerification(session) - .show(context.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) - } - } - - override fun upgradeSessionSecurity(context: Context, initCrossSigningOnly: Boolean) { - if (context is AppCompatActivity) { - BootstrapBottomSheet.show( - context.supportFragmentManager, - if (initCrossSigningOnly) SetupMode.CROSS_SIGNING_ONLY else SetupMode.NORMAL + if (otherSessions.isNotEmpty()) { + val pr = session.cryptoService().verificationService().requestKeyVerification( + supportedVerificationMethodsProvider.provide(), + session.myUserId, + otherSessions ) + VerificationBottomSheet.forSelfVerification(session, pr.transactionId ?: pr.localId) + .show(fragmentActivity.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + } else { + VerificationBottomSheet.forSelfVerification(session) + .show(fragmentActivity.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) } } + override fun waitSessionVerification(fragmentActivity: FragmentActivity) { + val session = sessionHolder.getSafeActiveSession() ?: return + VerificationBottomSheet.forSelfVerification(session) + .show(fragmentActivity.supportFragmentManager, VerificationBottomSheet.WAITING_SELF_VERIF_TAG) + } + + override fun upgradeSessionSecurity(fragmentActivity: FragmentActivity, initCrossSigningOnly: Boolean) { + BootstrapBottomSheet.show( + fragmentActivity.supportFragmentManager, + if (initCrossSigningOnly) SetupMode.CROSS_SIGNING_ONLY else SetupMode.NORMAL + ) + } + override fun openRoomMemberProfile(userId: String, roomId: String?, context: Context, buildTask: Boolean) { val args = RoomMemberProfileArgs(userId = userId, roomId = roomId) val intent = RoomMemberProfileActivity.newIntent(context, args) @@ -316,16 +306,14 @@ class DefaultNavigator @Inject constructor( context.startActivity(intent) } - override fun openMatrixToBottomSheet(context: Context, link: String, origin: OriginOfMatrixTo) { - if (context is AppCompatActivity) { - if (context !is MatrixToBottomSheet.InteractionListener) { - fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast()) - return - } - // TODO check if there is already one?? - MatrixToBottomSheet.withLink(link, origin) - .show(context.supportFragmentManager, "HA#MatrixToBottomSheet") + override fun openMatrixToBottomSheet(fragmentActivity: FragmentActivity, link: String, origin: OriginOfMatrixTo) { + if (fragmentActivity !is MatrixToBottomSheet.InteractionListener) { + fatalError("Caller context should implement MatrixToBottomSheet.InteractionListener", vectorPreferences.failFast()) + return } + // TODO check if there is already one?? + MatrixToBottomSheet.withLink(link, origin) + .show(fragmentActivity.supportFragmentManager, "HA#MatrixToBottomSheet") } override fun openRoomDirectory(context: Context, initialFilter: String) { @@ -347,18 +335,16 @@ class DefaultNavigator @Inject constructor( }.start(context) } - override fun openInviteUsersToRoom(context: Context, roomId: String) { + override fun openInviteUsersToRoom(fragmentActivity: FragmentActivity, roomId: String) { when (val currentSpace = spaceStateHandler.getCurrentSpace()) { - null -> InviteUsersToRoomActivity.getIntent(context, roomId).start(context) - else -> showInviteToDialog(context, currentSpace, roomId) + null -> InviteUsersToRoomActivity.getIntent(fragmentActivity, roomId).start(fragmentActivity) + else -> showInviteToDialog(fragmentActivity, currentSpace, roomId) } } - private fun showInviteToDialog(context: Context, currentSpace: RoomSummary, roomId: String) { - (context as? AppCompatActivity)?.supportFragmentManager?.let { fragmentManager -> - InviteRoomSpaceChooserBottomSheet.showInstance(fragmentManager, currentSpace.roomId, roomId) { itemId -> - InviteUsersToRoomActivity.getIntent(context, itemId).start(context) - } + private fun showInviteToDialog(fragmentActivity: FragmentActivity, currentSpace: RoomSummary, roomId: String) { + InviteRoomSpaceChooserBottomSheet.showInstance(fragmentActivity.supportFragmentManager, currentSpace.roomId, roomId) { itemId -> + InviteUsersToRoomActivity.getIntent(fragmentActivity, itemId).start(fragmentActivity) } } @@ -381,24 +367,20 @@ class DefaultNavigator @Inject constructor( debugNavigator.openDebugMenu(context) } - override fun openKeysBackupSetup(context: Context, showManualExport: Boolean) { + override fun openKeysBackupSetup(fragmentActivity: FragmentActivity, showManualExport: Boolean) { // if cross signing is enabled and trusted or not set up at all we should propose full 4S sessionHolder.getSafeActiveSession()?.let { session -> if (session.cryptoService().crossSigningService().getMyCrossSigningKeys() == null || session.cryptoService().crossSigningService().canCrossSign()) { - (context as? AppCompatActivity)?.let { - BootstrapBottomSheet.show(it.supportFragmentManager, SetupMode.NORMAL) - } + BootstrapBottomSheet.show(fragmentActivity.supportFragmentManager, SetupMode.NORMAL) } else { - context.startActivity(KeysBackupSetupActivity.intent(context, showManualExport)) + fragmentActivity.startActivity(KeysBackupSetupActivity.intent(fragmentActivity, showManualExport)) } } } - override fun open4SSetup(context: Context, setupMode: SetupMode) { - if (context is AppCompatActivity) { - BootstrapBottomSheet.show(context.supportFragmentManager, setupMode) - } + override fun open4SSetup(fragmentActivity: FragmentActivity, setupMode: SetupMode) { + BootstrapBottomSheet.show(fragmentActivity.supportFragmentManager, setupMode) } override fun openKeysBackupManager(context: Context) { diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 5d86456ba5..3521a02775 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -23,6 +23,7 @@ import android.net.Uri import android.view.View import androidx.activity.result.ActivityResultLauncher import androidx.core.util.Pair +import androidx.fragment.app.FragmentActivity import im.vector.app.features.analytics.plan.ViewRoom import im.vector.app.features.crypto.recover.SetupMode import im.vector.app.features.displayname.getBestName @@ -76,15 +77,15 @@ interface Navigator { fun openSpacePreview(context: Context, spaceId: String) - fun performDeviceVerification(context: Context, otherUserId: String, sasTransactionId: String) + fun performDeviceVerification(fragmentActivity: FragmentActivity, otherUserId: String, sasTransactionId: String) - fun requestSessionVerification(context: Context, otherSessionId: String) + fun requestSessionVerification(fragmentActivity: FragmentActivity, otherSessionId: String) - fun requestSelfSessionVerification(context: Context) + fun requestSelfSessionVerification(fragmentActivity: FragmentActivity) - fun waitSessionVerification(context: Context) + fun waitSessionVerification(fragmentActivity: FragmentActivity) - fun upgradeSessionSecurity(context: Context, initCrossSigningOnly: Boolean) + fun upgradeSessionSecurity(fragmentActivity: FragmentActivity, initCrossSigningOnly: Boolean) fun openRoomForSharingAndFinish(activity: Activity, roomId: String, sharedData: SharedData) @@ -92,13 +93,13 @@ interface Navigator { fun openRoomPreview(context: Context, roomPreviewData: RoomPreviewData, fromEmailInviteLink: PermalinkData.RoomEmailInviteLink? = null) - fun openMatrixToBottomSheet(context: Context, link: String, origin: OriginOfMatrixTo) + fun openMatrixToBottomSheet(fragmentActivity: FragmentActivity, link: String, origin: OriginOfMatrixTo) fun openCreateRoom(context: Context, initialName: String = "", openAfterCreate: Boolean = true) fun openCreateDirectRoom(context: Context) - fun openInviteUsersToRoom(context: Context, roomId: String) + fun openInviteUsersToRoom(fragmentActivity: FragmentActivity, roomId: String) fun openRoomDirectory(context: Context, initialFilter: String = "") @@ -110,9 +111,9 @@ interface Navigator { fun openDebug(context: Context) - fun openKeysBackupSetup(context: Context, showManualExport: Boolean) + fun openKeysBackupSetup(fragmentActivity: FragmentActivity, showManualExport: Boolean) - fun open4SSetup(context: Context, setupMode: SetupMode) + fun open4SSetup(fragmentActivity: FragmentActivity, setupMode: SetupMode) fun openKeysBackupManager(context: Context) diff --git a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt index fc56891b72..18b9f03444 100644 --- a/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt +++ b/vector/src/main/java/im/vector/app/features/permalink/PermalinkHandler.kt @@ -19,6 +19,7 @@ package im.vector.app.features.permalink import android.content.Context import android.net.Uri import androidx.core.net.toUri +import androidx.fragment.app.FragmentActivity import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.extensions.isIgnored @@ -52,17 +53,17 @@ class PermalinkHandler @Inject constructor( ) { suspend fun launch( - context: Context, + fragmentActivity: FragmentActivity, deepLink: String?, navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false ): Boolean { val uri = deepLink?.let { Uri.parse(it) } - return launch(context, uri, navigationInterceptor, buildTask) + return launch(fragmentActivity, uri, navigationInterceptor, buildTask) } suspend fun launch( - context: Context, + fragmentActivity: FragmentActivity, deepLink: Uri?, navigationInterceptor: NavigationInterceptor? = null, buildTask: Boolean = false @@ -70,12 +71,12 @@ class PermalinkHandler @Inject constructor( return when { deepLink == null -> false deepLink.isIgnored() -> true - !isPermalinkSupported(context, deepLink.toString()) -> false + !isPermalinkSupported(fragmentActivity, deepLink.toString()) -> false else -> { tryOrNull { withContext(Dispatchers.Default) { val permalinkData = PermalinkParser.parse(deepLink) - handlePermalink(permalinkData, deepLink, context, navigationInterceptor, buildTask) + handlePermalink(permalinkData, deepLink, fragmentActivity, navigationInterceptor, buildTask) } } ?: false } @@ -85,22 +86,22 @@ class PermalinkHandler @Inject constructor( private suspend fun handlePermalink( permalinkData: PermalinkData, rawLink: Uri, - context: Context, + fragmentActivity: FragmentActivity, navigationInterceptor: NavigationInterceptor?, buildTask: Boolean ): Boolean { return when (permalinkData) { - is PermalinkData.RoomLink -> handleRoomLink(permalinkData, rawLink, context, navigationInterceptor, buildTask) - is PermalinkData.UserLink -> handleUserLink(permalinkData, rawLink, context, navigationInterceptor, buildTask) - is PermalinkData.FallbackLink -> handleFallbackLink(permalinkData, context) - is PermalinkData.RoomEmailInviteLink -> handleRoomInviteLink(permalinkData, context) + is PermalinkData.RoomLink -> handleRoomLink(permalinkData, rawLink, fragmentActivity, navigationInterceptor, buildTask) + is PermalinkData.UserLink -> handleUserLink(permalinkData, rawLink, fragmentActivity, navigationInterceptor, buildTask) + is PermalinkData.FallbackLink -> handleFallbackLink(permalinkData, fragmentActivity) + is PermalinkData.RoomEmailInviteLink -> handleRoomInviteLink(permalinkData, fragmentActivity) } } private suspend fun handleRoomLink( permalinkData: PermalinkData.RoomLink, rawLink: Uri, - context: Context, + fragmentActivity: FragmentActivity, navigationInterceptor: NavigationInterceptor?, buildTask: Boolean ): Boolean { @@ -119,7 +120,7 @@ class PermalinkHandler @Inject constructor( } openRoom( navigationInterceptor, - context = context, + fragmentActivity = fragmentActivity, roomId = roomId, permalinkData = permalinkData, rawLink = rawLink, @@ -200,7 +201,7 @@ class PermalinkHandler @Inject constructor( */ private fun openRoom( navigationInterceptor: NavigationInterceptor?, - context: Context, + fragmentActivity: FragmentActivity, roomId: String?, permalinkData: PermalinkData.RoomLink, rawLink: Uri, @@ -209,7 +210,7 @@ class PermalinkHandler @Inject constructor( ) { val session = activeSessionHolder.getSafeActiveSession() ?: return if (roomId == null) { - context.toast(R.string.room_error_not_found) + fragmentActivity.toast(R.string.room_error_not_found) return } val roomSummary = session.getRoomSummary(roomId) @@ -218,19 +219,19 @@ class PermalinkHandler @Inject constructor( // val roomAlias = permalinkData.getRoomAliasOrNull() val isSpace = roomSummary?.roomType == RoomType.SPACE return when { - membership == Membership.BAN -> context.toast(R.string.error_opening_banned_room) + membership == Membership.BAN -> fragmentActivity.toast(R.string.error_opening_banned_room) membership?.isActive().orFalse() -> { if (!isSpace && membership == Membership.JOIN) { // If it's a room you're in, let's just open it, you can tap back if needed - navigationInterceptor.openJoinedRoomScreen(buildTask, roomId, eventId, rawLink, context, rootThreadEventId, roomSummary) + navigationInterceptor.openJoinedRoomScreen(buildTask, roomId, eventId, rawLink, fragmentActivity, rootThreadEventId, roomSummary) } else { - // maybe open space preview navigator.openSpacePreview(context, roomId)? if already joined? - navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK) + // maybe open space preview navigator.openSpacePreview(fragmentActivity, roomId)? if already joined? + navigator.openMatrixToBottomSheet(fragmentActivity, rawLink.toString(), OriginOfMatrixTo.LINK) } } else -> { // XXX this could trigger another server load - navigator.openMatrixToBottomSheet(context, rawLink.toString(), OriginOfMatrixTo.LINK) + navigator.openMatrixToBottomSheet(fragmentActivity, rawLink.toString(), OriginOfMatrixTo.LINK) } } } 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 847c675c5e..7b5cc20910 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 @@ -130,7 +130,7 @@ class PublicRoomsFragment : viewLifecycleOwner.lifecycleScope.launch { val permalink = session.permalinkService().createPermalink(roomIdOrAlias) val isHandled = permalinkHandler - .launch(requireContext(), permalink, object : NavigationInterceptor { + .launch(requireActivity(), permalink, object : NavigationInterceptor { override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?, rootThreadEventId: String?): Boolean { requireActivity().finish() return false 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 259fde1635..8ed8db8c6b 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 @@ -76,7 +76,7 @@ class RoomMemberListFragment : private fun setupInviteUsersButton() { views.inviteUsersButton.debouncedClicks { - navigator.openInviteUsersToRoom(requireContext(), roomProfileArgs.roomId) + navigator.openInviteUsersToRoom(requireActivity(), roomProfileArgs.roomId) } // Hide FAB when list is scrolling views.roomSettingGeneric.roomSettingsRecyclerView.addOnScrollListener( 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 2d82e48aac..5b19b7a8d2 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 @@ -94,7 +94,7 @@ class VectorSettingsDevicesFragment : } } is DevicesViewEvents.PromptResetSecrets -> { - navigator.open4SSetup(requireContext(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) + navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt index 78b8c66f9c..4bb1d1131b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/VectorSettingsDevicesFragment.kt @@ -99,7 +99,7 @@ class VectorSettingsDevicesFragment : } } is DevicesViewEvents.PromptResetSecrets -> { - navigator.open4SSetup(requireContext(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) + navigator.open4SSetup(requireActivity(), SetupMode.PASSPHRASE_AND_NEEDED_SECRETS_RESET) } } } diff --git a/vector/src/main/res/drawable-hdpi/ill_app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-hdpi/ill_app_layout_onboarding_spaces.webp index 35f2a04236..f1fe6c70b7 100644 Binary files a/vector/src/main/res/drawable-hdpi/ill_app_layout_onboarding_spaces.webp and b/vector/src/main/res/drawable-hdpi/ill_app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-mdpi/ill_app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-mdpi/ill_app_layout_onboarding_spaces.webp index a77bce20e8..8e16d650e4 100644 Binary files a/vector/src/main/res/drawable-mdpi/ill_app_layout_onboarding_spaces.webp and b/vector/src/main/res/drawable-mdpi/ill_app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xhdpi/ill_app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xhdpi/ill_app_layout_onboarding_spaces.webp index 9b5b9fa607..652bc6c77c 100644 Binary files a/vector/src/main/res/drawable-xhdpi/ill_app_layout_onboarding_spaces.webp and b/vector/src/main/res/drawable-xhdpi/ill_app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xxhdpi/ill_app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xxhdpi/ill_app_layout_onboarding_spaces.webp index 03e31dc9d6..9cf1ea9187 100644 Binary files a/vector/src/main/res/drawable-xxhdpi/ill_app_layout_onboarding_spaces.webp and b/vector/src/main/res/drawable-xxhdpi/ill_app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xxxhdpi/ill_app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xxxhdpi/ill_app_layout_onboarding_spaces.webp index b4bf421be5..e7d07defe2 100644 Binary files a/vector/src/main/res/drawable-xxxhdpi/ill_app_layout_onboarding_spaces.webp and b/vector/src/main/res/drawable-xxxhdpi/ill_app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable/ic_open_spaces.xml b/vector/src/main/res/drawable/ic_open_spaces.xml deleted file mode 100644 index 180f71f1cd..0000000000 --- a/vector/src/main/res/drawable/ic_open_spaces.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - diff --git a/vector/src/main/res/drawable/ic_spaces.xml b/vector/src/main/res/drawable/ic_spaces.xml new file mode 100644 index 0000000000..113bfb68f4 --- /dev/null +++ b/vector/src/main/res/drawable/ic_spaces.xml @@ -0,0 +1,26 @@ + + + + + + diff --git a/vector/src/main/res/layout/fragment_new_home_detail.xml b/vector/src/main/res/layout/fragment_new_home_detail.xml index 7800752e75..ced71a7863 100644 --- a/vector/src/main/res/layout/fragment_new_home_detail.xml +++ b/vector/src/main/res/layout/fragment_new_home_detail.xml @@ -109,7 +109,7 @@ android:layout_marginBottom="20dp" android:accessibilityTraversalAfter="@id/newLayoutCreateChatButton" android:contentDescription="@string/a11y_open_spaces" - android:src="@drawable/ic_open_spaces" + android:src="@drawable/ic_spaces" android:visibility="gone" app:backgroundTint="?attr/vctr_toolbar_background" app:fabSize="mini" diff --git a/vector/src/main/res/layout/fragment_space_list.xml b/vector/src/main/res/layout/fragment_space_list.xml index 8dfbb4a9c6..e2822495bf 100644 --- a/vector/src/main/res/layout/fragment_space_list.xml +++ b/vector/src/main/res/layout/fragment_space_list.xml @@ -9,6 +9,7 @@ android:id="@+id/groupListView" android:layout_width="match_parent" android:layout_height="match_parent" + android:minHeight="195dp" android:overScrollMode="always" tools:listitem="@layout/item_space" /> diff --git a/vector/src/main/res/layout/item_recent_room.xml b/vector/src/main/res/layout/item_recent_room.xml index 2cd8ff49c5..b2d311d328 100644 --- a/vector/src/main/res/layout/item_recent_room.xml +++ b/vector/src/main/res/layout/item_recent_room.xml @@ -3,12 +3,13 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/recentRoot" - android:layout_width="60dp" + android:layout_width="84dp" android:layout_height="wrap_content" android:background="?vctr_toolbar_background" android:clickable="true" android:focusable="true" android:foreground="?attr/selectableItemBackground" + android:paddingHorizontal="12dp" tools:viewBindingIgnore="true">