diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt index 6e4ecf4775..6d7c3d39e6 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Activity.kt @@ -21,31 +21,31 @@ import androidx.fragment.app.Fragment import im.vector.riotx.core.platform.VectorBaseActivity fun VectorBaseActivity.addFragment(frameId: Int, fragment: Fragment) { - supportFragmentManager.inTransaction { add(frameId, fragment) } + supportFragmentManager.commitTransactionNow { add(frameId, fragment) } } fun VectorBaseActivity.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseActivity.replaceFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - supportFragmentManager.inTransaction { replace(frameId, fragment, tag) } + supportFragmentManager.commitTransactionNow { replace(frameId, fragment, tag) } } fun VectorBaseActivity.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - supportFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + supportFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } } fun VectorBaseActivity.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt index f96b773990..7db27ececb 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/Fragment.kt @@ -21,61 +21,61 @@ import androidx.fragment.app.Fragment import im.vector.riotx.core.platform.VectorBaseFragment fun VectorBaseFragment.addFragment(frameId: Int, fragment: Fragment) { - parentFragmentManager.inTransaction { add(frameId, fragment) } + parentFragmentManager.commitTransactionNow { add(frameId, fragment) } } fun VectorBaseFragment.addFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.replaceFragment(frameId: Int, fragment: Fragment) { - parentFragmentManager.inTransaction { replace(frameId, fragment) } + parentFragmentManager.commitTransactionNow { replace(frameId, fragment) } } fun VectorBaseFragment.replaceFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - parentFragmentManager.inTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } + parentFragmentManager.commitTransaction { replace(frameId, fragment, tag).addToBackStack(tag) } } fun VectorBaseFragment.addFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - parentFragmentManager.inTransaction { + parentFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } fun VectorBaseFragment.addChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { add(frameId, fragment, tag) } + childFragmentManager.commitTransactionNow { add(frameId, fragment, tag) } } fun VectorBaseFragment.addChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransactionNow { add(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { replace(frameId, fragment, tag) } + childFragmentManager.commitTransactionNow { replace(frameId, fragment, tag) } } fun VectorBaseFragment.replaceChildFragment(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransactionNow { replace(frameId, fragmentClass, params.toMvRxBundle(), tag) } } fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragment: Fragment, tag: String? = null) { - childFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) } + childFragmentManager.commitTransaction { replace(frameId, fragment).addToBackStack(tag) } } fun VectorBaseFragment.addChildFragmentToBackstack(frameId: Int, fragmentClass: Class, params: Parcelable? = null, tag: String? = null) { - childFragmentManager.inTransaction { + childFragmentManager.commitTransaction { replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag) } } diff --git a/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt b/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt index 1d7815b2b7..caf1bf90f8 100644 --- a/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt +++ b/vector/src/main/java/im/vector/riotx/core/extensions/FragmentManager.kt @@ -18,6 +18,10 @@ package im.vector.riotx.core.extensions import androidx.fragment.app.FragmentTransaction -inline fun androidx.fragment.app.FragmentManager.inTransaction(func: FragmentTransaction.() -> FragmentTransaction) { +inline fun androidx.fragment.app.FragmentManager.commitTransactionNow(func: FragmentTransaction.() -> FragmentTransaction) { + beginTransaction().func().commitNow() +} + +inline fun androidx.fragment.app.FragmentManager.commitTransaction(func: FragmentTransaction.() -> FragmentTransaction) { beginTransaction().func().commit() } diff --git a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt index cb5391be3c..cf80bf98fc 100644 --- a/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/crypto/verification/SASVerificationActivity.kt @@ -26,7 +26,7 @@ import im.vector.matrix.android.api.session.crypto.sas.IncomingSasVerificationTr import im.vector.matrix.android.api.session.crypto.sas.OutgoingSasVerificationRequest import im.vector.matrix.android.api.session.crypto.sas.SasVerificationTxState import im.vector.riotx.R -import im.vector.riotx.core.extensions.inTransaction +import im.vector.riotx.core.extensions.commitTransaction import im.vector.riotx.core.extensions.observeEvent import im.vector.riotx.core.platform.SimpleFragmentActivity import im.vector.riotx.core.platform.WaitingViewData @@ -102,20 +102,20 @@ class SASVerificationActivity : SimpleFragmentActivity() { IncomingSasVerificationTransaction.UxState.SHOW_ACCEPT, IncomingSasVerificationTransaction.UxState.WAIT_FOR_KEY_AGREEMENT -> { supportActionBar?.setTitle(R.string.sas_incoming_request_title) - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationIncomingFragment::class.java, null) } } IncomingSasVerificationTransaction.UxState.WAIT_FOR_VERIFICATION, IncomingSasVerificationTransaction.UxState.SHOW_SAS -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } IncomingSasVerificationTransaction.UxState.VERIFIED -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } @@ -133,20 +133,20 @@ class SASVerificationActivity : SimpleFragmentActivity() { OutgoingSasVerificationRequest.UxState.UNKNOWN, OutgoingSasVerificationRequest.UxState.WAIT_FOR_START, OutgoingSasVerificationRequest.UxState.WAIT_FOR_KEY_AGREEMENT -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationStartFragment::class.java, null) } } OutgoingSasVerificationRequest.UxState.SHOW_SAS, OutgoingSasVerificationRequest.UxState.WAIT_FOR_VERIFICATION -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } OutgoingSasVerificationRequest.UxState.VERIFIED -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.no_anim, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } @@ -172,13 +172,13 @@ class SASVerificationActivity : SimpleFragmentActivity() { finish() } SasVerificationViewModel.NAVIGATE_SAS_DISPLAY -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) replace(R.id.container, SASVerificationShortCodeFragment::class.java, null) } } SasVerificationViewModel.NAVIGATE_SUCCESS -> { - supportFragmentManager.inTransaction { + supportFragmentManager.commitTransaction { setCustomAnimations(R.anim.enter_from_right, R.anim.exit_fade_out) replace(R.id.container, SASVerificationVerifiedFragment::class.java, null) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt index 189a1e8aeb..b4064f270e 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailAction.kt @@ -20,5 +20,5 @@ import im.vector.riotx.core.platform.VectorViewModelAction import im.vector.riotx.features.home.room.list.RoomListFragment sealed class HomeDetailAction : VectorViewModelAction { - data class SwitchDisplayMode(val displayMode: RoomListFragment.DisplayMode) : HomeDetailAction() + data class SwitchDisplayMode(val displayMode: RoomListDisplayMode) : HomeDetailAction() } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt index 7aa96d0b8d..1c78acbcfe 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailFragment.kt @@ -29,8 +29,8 @@ import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.riotx.R -import im.vector.riotx.core.extensions.inTransaction -import im.vector.riotx.core.extensions.replaceChildFragment +import im.vector.riotx.core.extensions.commitTransaction +import im.vector.riotx.core.extensions.commitTransactionNow import im.vector.riotx.core.platform.ToolbarConfigurable import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.ui.views.KeysBackupBanner @@ -134,10 +134,10 @@ class HomeDetailFragment @Inject constructor( private fun setupBottomNavigationView() { bottomNavigationView.setOnNavigationItemSelectedListener { val displayMode = when (it.itemId) { - R.id.bottom_action_home -> RoomListFragment.DisplayMode.HOME - R.id.bottom_action_people -> RoomListFragment.DisplayMode.PEOPLE - R.id.bottom_action_rooms -> RoomListFragment.DisplayMode.ROOMS - else -> RoomListFragment.DisplayMode.HOME + R.id.bottom_action_home -> RoomListDisplayMode.HOME + R.id.bottom_action_people -> RoomListDisplayMode.PEOPLE + R.id.bottom_action_rooms -> RoomListDisplayMode.ROOMS + else -> RoomListDisplayMode.HOME } viewModel.handle(HomeDetailAction.SwitchDisplayMode(displayMode)) true @@ -153,22 +153,26 @@ class HomeDetailFragment @Inject constructor( } } - private fun switchDisplayMode(displayMode: RoomListFragment.DisplayMode) { + private fun switchDisplayMode(displayMode: RoomListDisplayMode) { groupToolbarTitleView.setText(displayMode.titleRes) updateSelectedFragment(displayMode) // Update the navigation view (for when we restore the tabs) bottomNavigationView.selectedItemId = when (displayMode) { - RoomListFragment.DisplayMode.PEOPLE -> R.id.bottom_action_people - RoomListFragment.DisplayMode.ROOMS -> R.id.bottom_action_rooms + RoomListDisplayMode.PEOPLE -> R.id.bottom_action_people + RoomListDisplayMode.ROOMS -> R.id.bottom_action_rooms else -> R.id.bottom_action_home } } - private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) { + private fun updateSelectedFragment(displayMode: RoomListDisplayMode) { val fragmentTag = "FRAGMENT_TAG_${displayMode.name}" val fragmentToShow = childFragmentManager.findFragmentByTag(fragmentTag) - childFragmentManager.inTransaction { - childFragmentManager.fragments.forEach { hide(it) } + childFragmentManager.commitTransactionNow { + childFragmentManager.fragments + .filter { it != fragmentToShow } + .forEach { + hide(it) + } if (fragmentToShow == null) { val params = RoomListParams(displayMode) add(R.id.roomListContainer, RoomListFragment::class.java, params.toMvRxBundle(), fragmentTag) diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt index ca552dc234..6b38fb34b1 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewModel.kt @@ -22,11 +22,17 @@ import com.airbnb.mvrx.ViewModelContext import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import im.vector.matrix.android.api.session.Session +import im.vector.matrix.android.api.session.room.model.Membership +import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.matrix.rx.rx import im.vector.riotx.core.di.HasScreenInjector import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.resources.StringProvider import im.vector.riotx.features.home.group.SelectedGroupDataSource +import im.vector.riotx.features.home.room.list.RoomCategory +import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.room.list.RoomSummaries import im.vector.riotx.features.ui.UiStateRepository import io.reactivex.schedulers.Schedulers @@ -144,4 +150,5 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho } .disposeOnClear() } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt index b1c50b83cf..1fc3a1ef21 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/HomeDetailViewState.kt @@ -17,14 +17,19 @@ package im.vector.riotx.features.home import arrow.core.Option +import com.airbnb.mvrx.Async import com.airbnb.mvrx.MvRxState +import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.group.model.GroupSummary +import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.sync.SyncState import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.room.list.RoomSummaries data class HomeDetailViewState( val groupSummary: Option = Option.empty(), - val displayMode: RoomListFragment.DisplayMode = RoomListFragment.DisplayMode.HOME, + val asyncRooms: Async> = Uninitialized, + val displayMode: RoomListDisplayMode = RoomListDisplayMode.HOME, val notificationCountCatchup: Int = 0, val notificationHighlightCatchup: Boolean = false, val notificationCountPeople: Int = 0, diff --git a/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt b/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt new file mode 100644 index 0000000000..18b901a967 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/home/RoomListDisplayMode.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2019 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.riotx.features.home + +import androidx.annotation.StringRes +import im.vector.riotx.R + +enum class RoomListDisplayMode(@StringRes val titleRes: Int) { + HOME(R.string.bottom_action_home), + PEOPLE(R.string.bottom_action_people_x), + ROOMS(R.string.bottom_action_rooms), + FILTERED(/* Not used */ 0), + SHARE(/* Not used */ 0) + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 062a4be2d2..3dcd185518 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -286,6 +286,11 @@ class RoomDetailFragment @Inject constructor( } } + override fun onDestroyView() { + super.onDestroyView() + recyclerView.adapter = null + } + override fun onDestroy() { debouncer.cancelAll() super.onDestroy() @@ -472,6 +477,7 @@ class RoomDetailFragment @Inject constructor( } } recyclerView.adapter = timelineEventController.adapter + recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { if (recyclerView.scrollState == RecyclerView.SCROLL_STATE_IDLE) { @@ -492,6 +498,7 @@ class RoomDetailFragment @Inject constructor( } } }) + timelineEventController.callback = this if (vectorPreferences.swipeToReplyIsEnabled()) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt index a3302d40c3..c4bb0d9b15 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/filtered/FilteredRoomsActivity.kt @@ -24,6 +24,7 @@ import im.vector.riotx.R import im.vector.riotx.core.di.ScreenComponent import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.VectorBaseActivity +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListParams import kotlinx.android.synthetic.main.activity_filtered_rooms.* @@ -47,7 +48,7 @@ class FilteredRoomsActivity : VectorBaseActivity() { super.onCreate(savedInstanceState) configureToolbar(filteredRoomsToolbar) if (isFirstCreation()) { - val params = RoomListParams(RoomListFragment.DisplayMode.FILTERED) + val params = RoomListParams(RoomListDisplayMode.FILTERED) replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG) } filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt index 3ea6745a94..8cae1fd4e8 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListDisplayModeFilter.kt @@ -18,21 +18,22 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary +import im.vector.riotx.features.home.RoomListDisplayMode import io.reactivex.functions.Predicate -class RoomListDisplayModeFilter(private val displayMode: RoomListFragment.DisplayMode) : Predicate { +class RoomListDisplayModeFilter(private val displayMode: RoomListDisplayMode) : Predicate { override fun test(roomSummary: RoomSummary): Boolean { if (roomSummary.membership.isLeft()) { return false } return when (displayMode) { - RoomListFragment.DisplayMode.HOME -> + RoomListDisplayMode.HOME -> roomSummary.notificationCount > 0 || roomSummary.membership == Membership.INVITE || roomSummary.userDrafts.isNotEmpty() - RoomListFragment.DisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.ROOMS -> !roomSummary.isDirect && roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.FILTERED -> roomSummary.membership == Membership.JOIN - RoomListFragment.DisplayMode.SHARE -> roomSummary.membership == Membership.JOIN + RoomListDisplayMode.PEOPLE -> roomSummary.isDirect && roomSummary.membership == Membership.JOIN + RoomListDisplayMode.ROOMS -> !roomSummary.isDirect && roomSummary.membership == Membership.JOIN + RoomListDisplayMode.FILTERED -> roomSummary.membership == Membership.JOIN + RoomListDisplayMode.SHARE -> roomSummary.membership == Membership.JOIN } } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt index 92080c1b1f..73915493b9 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListFragment.kt @@ -39,6 +39,7 @@ import im.vector.riotx.core.error.ErrorFormatter import im.vector.riotx.core.platform.OnBackPressed import im.vector.riotx.core.platform.StateView import im.vector.riotx.core.platform.VectorBaseFragment +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedAction import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsBottomSheet import im.vector.riotx.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel @@ -46,15 +47,13 @@ import im.vector.riotx.features.home.room.list.widget.FabMenuView import im.vector.riotx.features.notifications.NotificationDrawerManager import im.vector.riotx.features.share.SharedData import io.reactivex.android.schedulers.AndroidSchedulers -import io.reactivex.functions.Consumer import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_room_list.* -import timber.log.Timber import javax.inject.Inject @Parcelize data class RoomListParams( - val displayMode: RoomListFragment.DisplayMode, + val displayMode: RoomListDisplayMode, val sharedData: SharedData? = null ) : Parcelable @@ -66,14 +65,6 @@ class RoomListFragment @Inject constructor( ) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener { - enum class DisplayMode(@StringRes val titleRes: Int) { - HOME(R.string.bottom_action_home), - PEOPLE(R.string.bottom_action_people_x), - ROOMS(R.string.bottom_action_rooms), - FILTERED(/* Not used */ 0), - SHARE(/* Not used */ 0) - } - private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel private val roomListParams: RoomListParams by args() private val roomListViewModel: RoomListViewModel by fragmentViewModel() @@ -126,8 +117,13 @@ class RoomListFragment @Inject constructor( .disposeOnDestroyView() } + override fun onDestroyView() { + super.onDestroyView() + roomListView.adapter = null + } + private fun openSelectedRoom(event: RoomListViewEvents.SelectRoom) { - if (roomListParams.displayMode == DisplayMode.SHARE) { + if (roomListParams.displayMode == RoomListDisplayMode.SHARE) { val sharedData = roomListParams.sharedData ?: return navigator.openRoomForSharing(requireActivity(), event.roomId, sharedData) } else { @@ -144,9 +140,9 @@ class RoomListFragment @Inject constructor( private fun setupCreateRoomButton() { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.isVisible = true - DisplayMode.PEOPLE -> createChatRoomButton.isVisible = true - DisplayMode.ROOMS -> createGroupRoomButton.isVisible = true + RoomListDisplayMode.HOME -> createChatFabMenu.isVisible = true + RoomListDisplayMode.PEOPLE -> createChatRoomButton.isVisible = true + RoomListDisplayMode.ROOMS -> createGroupRoomButton.isVisible = true else -> Unit // No button in this mode } @@ -158,7 +154,7 @@ class RoomListFragment @Inject constructor( } // Hide FAB when list is scrolling - roomListEpoxyRecyclerView.addOnScrollListener( + roomListView.addOnScrollListener( object : RecyclerView.OnScrollListener() { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { createChatFabMenu.removeCallbacks(showFabRunnable) @@ -170,9 +166,9 @@ class RoomListFragment @Inject constructor( RecyclerView.SCROLL_STATE_DRAGGING, RecyclerView.SCROLL_STATE_SETTLING -> { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.hide() - DisplayMode.PEOPLE -> createChatRoomButton.hide() - DisplayMode.ROOMS -> createGroupRoomButton.hide() + RoomListDisplayMode.HOME -> createChatFabMenu.hide() + RoomListDisplayMode.PEOPLE -> createChatRoomButton.hide() + RoomListDisplayMode.ROOMS -> createGroupRoomButton.hide() else -> Unit } } @@ -183,7 +179,7 @@ class RoomListFragment @Inject constructor( fun filterRoomsWith(filter: String) { // Scroll the list to top - roomListEpoxyRecyclerView.scrollToPosition(0) + roomListView.scrollToPosition(0) roomListViewModel.handle(RoomListAction.FilterWith(filter)) } @@ -199,20 +195,20 @@ class RoomListFragment @Inject constructor( private fun setupRecyclerView() { val layoutManager = LinearLayoutManager(context) val stateRestorer = LayoutManagerStateRestorer(layoutManager).register() - roomListEpoxyRecyclerView.layoutManager = layoutManager - roomListEpoxyRecyclerView.itemAnimator = RoomListAnimator() + roomListView.layoutManager = layoutManager + roomListView.itemAnimator = RoomListAnimator() roomController.listener = this roomController.addModelBuildListener { it.dispatchTo(stateRestorer) } - stateView.contentView = roomListEpoxyRecyclerView - roomListEpoxyRecyclerView.setController(roomController) + roomListView.adapter = roomController.adapter + stateView.contentView = roomListView } private val showFabRunnable = Runnable { if (isAdded) { when (roomListParams.displayMode) { - DisplayMode.HOME -> createChatFabMenu.show() - DisplayMode.PEOPLE -> createChatRoomButton.show() - DisplayMode.ROOMS -> createGroupRoomButton.show() + RoomListDisplayMode.HOME -> createChatFabMenu.show() + RoomListDisplayMode.PEOPLE -> createChatRoomButton.show() + RoomListDisplayMode.ROOMS -> createGroupRoomButton.show() else -> Unit } } @@ -258,9 +254,9 @@ class RoomListFragment @Inject constructor( // Mark all as read menu when (roomListParams.displayMode) { - DisplayMode.HOME, - DisplayMode.PEOPLE, - DisplayMode.ROOMS -> { + RoomListDisplayMode.HOME, + RoomListDisplayMode.PEOPLE, + RoomListDisplayMode.ROOMS -> { val newValue = state.hasUnread if (hasUnreadRooms != newValue) { hasUnreadRooms = newValue @@ -288,7 +284,7 @@ class RoomListFragment @Inject constructor( } .isNullOrEmpty() val emptyState = when (roomListParams.displayMode) { - DisplayMode.HOME -> { + RoomListDisplayMode.HOME -> { if (hasNoRoom) { StateView.State.Empty( getString(R.string.room_list_catchup_welcome_title), @@ -302,13 +298,13 @@ class RoomListFragment @Inject constructor( getString(R.string.room_list_catchup_empty_body)) } } - DisplayMode.PEOPLE -> + RoomListDisplayMode.PEOPLE -> StateView.State.Empty( getString(R.string.room_list_people_empty_title), ContextCompat.getDrawable(requireContext(), R.drawable.ic_home_bottom_chat), getString(R.string.room_list_people_empty_body) ) - DisplayMode.ROOMS -> + RoomListDisplayMode.ROOMS -> StateView.State.Empty( getString(R.string.room_list_rooms_empty_title), ContextCompat.getDrawable(requireContext(), R.drawable.ic_home_bottom_group), diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt index 6fd5d9763c..db4d634a05 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModel.kt @@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.room.model.tag.RoomTag import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.utils.DataSource import im.vector.riotx.core.utils.PublishDataSource +import im.vector.riotx.features.home.RoomListDisplayMode import io.reactivex.schedulers.Schedulers import timber.log.Timber import javax.inject.Inject @@ -232,11 +233,11 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState, } val roomComparator = when (displayMode) { - RoomListFragment.DisplayMode.HOME -> chronologicalRoomComparator - RoomListFragment.DisplayMode.PEOPLE -> chronologicalRoomComparator - RoomListFragment.DisplayMode.ROOMS -> chronologicalRoomComparator - RoomListFragment.DisplayMode.FILTERED -> chronologicalRoomComparator - RoomListFragment.DisplayMode.SHARE -> chronologicalRoomComparator + RoomListDisplayMode.HOME -> chronologicalRoomComparator + RoomListDisplayMode.PEOPLE -> chronologicalRoomComparator + RoomListDisplayMode.ROOMS -> chronologicalRoomComparator + RoomListDisplayMode.FILTERED -> chronologicalRoomComparator + RoomListDisplayMode.SHARE -> chronologicalRoomComparator } return RoomSummaries().apply { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt index 897e72d811..836a1afb29 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewModelFactory.kt @@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.list import im.vector.matrix.android.api.session.Session import im.vector.riotx.features.home.HomeRoomListDataSource +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.share.ShareRoomListDataSource import javax.inject.Inject import javax.inject.Provider @@ -32,7 +33,7 @@ class RoomListViewModelFactory @Inject constructor(private val session: Provider return RoomListViewModel( initialState, session.get(), - if (initialState.displayMode == RoomListFragment.DisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), + if (initialState.displayMode == RoomListDisplayMode.SHARE) shareRoomListDataSource.get() else homeRoomListDataSource.get(), alphabeticalRoomComparator.get(), chronologicalRoomComparator.get()) } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt index 505554a8fb..b41b4b9eeb 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomListViewState.kt @@ -23,9 +23,10 @@ import com.airbnb.mvrx.Uninitialized import im.vector.matrix.android.api.session.room.model.Membership import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R +import im.vector.riotx.features.home.RoomListDisplayMode data class RoomListViewState( - val displayMode: RoomListFragment.DisplayMode, + val displayMode: RoomListDisplayMode, val asyncRooms: Async> = Uninitialized, val roomFilter: String = "", val asyncFilteredRooms: Async = Uninitialized, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt index 3401e041b1..ca86191e8c 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/list/RoomSummaryController.kt @@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.riotx.R import im.vector.riotx.core.epoxy.noResultItem import im.vector.riotx.core.resources.StringProvider +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.filtered.FilteredRoomFooterItem import im.vector.riotx.features.home.room.filtered.filteredRoomFooterItem import javax.inject.Inject @@ -50,8 +51,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri override fun buildModels() { val nonNullViewState = viewState ?: return when (nonNullViewState.displayMode) { - RoomListFragment.DisplayMode.FILTERED, - RoomListFragment.DisplayMode.SHARE -> { + RoomListDisplayMode.FILTERED, + RoomListDisplayMode.SHARE -> { buildFilteredRooms(nonNullViewState) } else -> { @@ -92,7 +93,7 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri viewState.rejectingErrorRoomsIds) when { - viewState.displayMode == RoomListFragment.DisplayMode.FILTERED -> addFilterFooter(viewState) + viewState.displayMode == RoomListDisplayMode.FILTERED -> addFilterFooter(viewState) filteredSummaries.isEmpty() -> addEmptyFooter() } } diff --git a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt index 1ec020e1a0..33b0744d4f 100644 --- a/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/share/IncomingShareActivity.kt @@ -31,6 +31,7 @@ import im.vector.riotx.core.extensions.replaceFragment import im.vector.riotx.core.platform.VectorBaseActivity import im.vector.riotx.features.attachments.AttachmentsHelper import im.vector.riotx.features.home.LoadingFragment +import im.vector.riotx.features.home.RoomListDisplayMode import im.vector.riotx.features.home.room.list.RoomListFragment import im.vector.riotx.features.home.room.list.RoomListParams import im.vector.riotx.features.login.LoginActivity @@ -97,7 +98,7 @@ class IncomingShareActivity : } override fun onContentAttachmentsReady(attachments: List) { - val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Attachments(attachments)) + val roomListParams = RoomListParams(RoomListDisplayMode.SHARE, sharedData = SharedData.Attachments(attachments)) replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) } @@ -116,7 +117,7 @@ class IncomingShareActivity : return if (sharedText.isNullOrEmpty()) { false } else { - val roomListParams = RoomListParams(RoomListFragment.DisplayMode.SHARE, sharedData = SharedData.Text(sharedText)) + val roomListParams = RoomListParams(RoomListDisplayMode.SHARE, sharedData = SharedData.Text(sharedText)) replaceFragment(R.id.shareRoomListFragmentContainer, RoomListFragment::class.java, roomListParams) true } diff --git a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt index 85051a0137..f850d12422 100644 --- a/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt +++ b/vector/src/main/java/im/vector/riotx/features/ui/SharedPreferencesUiStateRepository.kt @@ -18,7 +18,7 @@ package im.vector.riotx.features.ui import android.content.SharedPreferences import androidx.core.content.edit -import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.RoomListDisplayMode import javax.inject.Inject /** @@ -26,21 +26,21 @@ import javax.inject.Inject */ class SharedPreferencesUiStateRepository @Inject constructor(private val sharedPreferences: SharedPreferences) : UiStateRepository { - override fun getDisplayMode(): RoomListFragment.DisplayMode { + override fun getDisplayMode(): RoomListDisplayMode { return when (sharedPreferences.getInt(KEY_DISPLAY_MODE, VALUE_DISPLAY_MODE_CATCHUP)) { - VALUE_DISPLAY_MODE_PEOPLE -> RoomListFragment.DisplayMode.PEOPLE - VALUE_DISPLAY_MODE_ROOMS -> RoomListFragment.DisplayMode.ROOMS - else -> RoomListFragment.DisplayMode.HOME + VALUE_DISPLAY_MODE_PEOPLE -> RoomListDisplayMode.PEOPLE + VALUE_DISPLAY_MODE_ROOMS -> RoomListDisplayMode.ROOMS + else -> RoomListDisplayMode.HOME } } - override fun storeDisplayMode(displayMode: RoomListFragment.DisplayMode) { + override fun storeDisplayMode(displayMode: RoomListDisplayMode) { sharedPreferences.edit { putInt(KEY_DISPLAY_MODE, when (displayMode) { - RoomListFragment.DisplayMode.PEOPLE -> VALUE_DISPLAY_MODE_PEOPLE - RoomListFragment.DisplayMode.ROOMS -> VALUE_DISPLAY_MODE_ROOMS - else -> VALUE_DISPLAY_MODE_CATCHUP + RoomListDisplayMode.PEOPLE -> VALUE_DISPLAY_MODE_PEOPLE + RoomListDisplayMode.ROOMS -> VALUE_DISPLAY_MODE_ROOMS + else -> VALUE_DISPLAY_MODE_CATCHUP }) } } diff --git a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt index 1c59a22892..feac6a64ed 100644 --- a/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt +++ b/vector/src/main/java/im/vector/riotx/features/ui/UiStateRepository.kt @@ -16,14 +16,14 @@ package im.vector.riotx.features.ui -import im.vector.riotx.features.home.room.list.RoomListFragment +import im.vector.riotx.features.home.RoomListDisplayMode /** * This interface is used to persist UI state across application restart */ interface UiStateRepository { - fun getDisplayMode(): RoomListFragment.DisplayMode + fun getDisplayMode(): RoomListDisplayMode - fun storeDisplayMode(displayMode: RoomListFragment.DisplayMode) + fun storeDisplayMode(displayMode: RoomListDisplayMode) } diff --git a/vector/src/main/res/layout/fragment_room_list.xml b/vector/src/main/res/layout/fragment_room_list.xml index 30ab86d004..2c828c8397 100644 --- a/vector/src/main/res/layout/fragment_room_list.xml +++ b/vector/src/main/res/layout/fragment_room_list.xml @@ -7,8 +7,8 @@ android:layout_height="match_parent" android:background="?riotx_header_panel_background"> - @@ -30,7 +30,7 @@ android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_direct_message" android:scaleType="center" android:src="@drawable/ic_fab_add_chat" @@ -47,7 +47,7 @@ android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="16dp" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_room" android:src="@drawable/ic_fab_add_room" android:visibility="gone" diff --git a/vector/src/main/res/layout/motion_fab_menu_merge.xml b/vector/src/main/res/layout/motion_fab_menu_merge.xml index 02ba4341c6..104db206cd 100644 --- a/vector/src/main/res/layout/motion_fab_menu_merge.xml +++ b/vector/src/main/res/layout/motion_fab_menu_merge.xml @@ -24,7 +24,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" - android:accessibilityTraversalBefore="@+id/roomListEpoxyRecyclerView" + android:accessibilityTraversalBefore="@+id/roomListView" android:contentDescription="@string/a11y_create_room" android:src="@drawable/ic_fab_add_room" app:backgroundTint="#FFFFFF"