added dialog to change app layout settings (#6840)
This commit is contained in:
		
							parent
							
								
									11b4ea5227
								
							
						
					
					
						commit
						0629cae183
					
				
							
								
								
									
										1
									
								
								changelog.d/6506.wip
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								changelog.d/6506.wip
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | [App Layout] added dialog to configure app layout | ||||||
| @ -56,6 +56,7 @@ import im.vector.app.features.analytics.plan.MobileScreen | |||||||
| import im.vector.app.features.analytics.plan.ViewRoom | import im.vector.app.features.analytics.plan.ViewRoom | ||||||
| import im.vector.app.features.crypto.recover.SetupMode | import im.vector.app.features.crypto.recover.SetupMode | ||||||
| import im.vector.app.features.disclaimer.showDisclaimerDialog | import im.vector.app.features.disclaimer.showDisclaimerDialog | ||||||
|  | import im.vector.app.features.home.room.list.home.layout.HomeLayoutSettingBottomDialogFragment | ||||||
| import im.vector.app.features.matrixto.MatrixToBottomSheet | import im.vector.app.features.matrixto.MatrixToBottomSheet | ||||||
| import im.vector.app.features.matrixto.OriginOfMatrixTo | import im.vector.app.features.matrixto.OriginOfMatrixTo | ||||||
| import im.vector.app.features.navigation.Navigator | import im.vector.app.features.navigation.Navigator | ||||||
| @ -283,6 +284,11 @@ class HomeActivity : | |||||||
|                 .show(supportFragmentManager, "SPACE_SETTINGS") |                 .show(supportFragmentManager, "SPACE_SETTINGS") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private fun showLayoutSettings() { | ||||||
|  |         HomeLayoutSettingBottomDialogFragment() | ||||||
|  |                 .show(supportFragmentManager, "LAYOUT_SETTINGS") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private fun openSpaceInvite(spaceId: String) { |     private fun openSpaceInvite(spaceId: String) { | ||||||
|         SpaceInviteBottomSheet.newInstance(spaceId) |         SpaceInviteBottomSheet.newInstance(spaceId) | ||||||
|                 .show(supportFragmentManager, "SPACE_INVITE") |                 .show(supportFragmentManager, "SPACE_INVITE") | ||||||
| @ -596,6 +602,10 @@ class HomeActivity : | |||||||
|                 navigator.openSettings(this) |                 navigator.openSettings(this) | ||||||
|                 true |                 true | ||||||
|             } |             } | ||||||
|  |             R.id.menu_home_layout_settings -> { | ||||||
|  |                 showLayoutSettings() | ||||||
|  |                 true | ||||||
|  |             } | ||||||
|             R.id.menu_home_invite_friends -> { |             R.id.menu_home_invite_friends -> { | ||||||
|                 launchInviteFriends() |                 launchInviteFriends() | ||||||
|                 true |                 true | ||||||
|  | |||||||
| @ -0,0 +1,70 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2022 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.app.features.home.room.list.home | ||||||
|  | 
 | ||||||
|  | import android.content.Context | ||||||
|  | import androidx.datastore.core.DataStore | ||||||
|  | import androidx.datastore.preferences.core.Preferences | ||||||
|  | import androidx.datastore.preferences.core.booleanPreferencesKey | ||||||
|  | import androidx.datastore.preferences.core.edit | ||||||
|  | import androidx.datastore.preferences.preferencesDataStore | ||||||
|  | import kotlinx.coroutines.flow.Flow | ||||||
|  | import kotlinx.coroutines.flow.distinctUntilChanged | ||||||
|  | import kotlinx.coroutines.flow.map | ||||||
|  | import org.matrix.android.sdk.api.extensions.orFalse | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "layout_preferences") | ||||||
|  | 
 | ||||||
|  | class HomeLayoutPreferencesStore @Inject constructor( | ||||||
|  |         private val context: Context | ||||||
|  | ) { | ||||||
|  | 
 | ||||||
|  |     private val areRecentsEnbabled = booleanPreferencesKey("SETTINGS_PREFERENCES_HOME_RECENTS") | ||||||
|  |     private val areFiltersEnabled = booleanPreferencesKey("SETTINGS_PREFERENCES_HOME_FILTERS") | ||||||
|  |     private val isAZOrderingEnabled = booleanPreferencesKey("SETTINGS_PREFERENCES_USE_AZ_ORDER") | ||||||
|  | 
 | ||||||
|  |     val areRecentsEnabledFlow: Flow<Boolean> = context.dataStore.data | ||||||
|  |             .map { preferences -> preferences[areRecentsEnbabled].orFalse() } | ||||||
|  |             .distinctUntilChanged() | ||||||
|  | 
 | ||||||
|  |     val areFiltersEnabledFlow: Flow<Boolean> = context.dataStore.data | ||||||
|  |             .map { preferences -> preferences[areFiltersEnabled].orFalse() } | ||||||
|  |             .distinctUntilChanged() | ||||||
|  | 
 | ||||||
|  |     val isAZOrderingEnabledFlow: Flow<Boolean> = context.dataStore.data | ||||||
|  |             .map { preferences -> preferences[isAZOrderingEnabled].orFalse() } | ||||||
|  |             .distinctUntilChanged() | ||||||
|  | 
 | ||||||
|  |     suspend fun setRecentsEnabled(isEnabled: Boolean) { | ||||||
|  |         context.dataStore.edit { settings -> | ||||||
|  |             settings[areRecentsEnbabled] = isEnabled | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     suspend fun setFiltersEnabled(isEnabled: Boolean) { | ||||||
|  |         context.dataStore.edit { settings -> | ||||||
|  |             settings[areFiltersEnabled] = isEnabled | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     suspend fun setAZOrderingEnabled(isEnabled: Boolean) { | ||||||
|  |         context.dataStore.edit { settings -> | ||||||
|  |             settings[isAZOrderingEnabled] = isEnabled | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -162,6 +162,15 @@ class HomeRoomListFragment @Inject constructor( | |||||||
|         }.launchIn(lifecycleScope) |         }.launchIn(lifecycleScope) | ||||||
| 
 | 
 | ||||||
|         views.roomListView.adapter = concatAdapter |         views.roomListView.adapter = concatAdapter | ||||||
|  | 
 | ||||||
|  |         // we need to force scroll when recents/filter tabs are added to make them visible | ||||||
|  |         concatAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { | ||||||
|  |             override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { | ||||||
|  |                 if (positionStart == 0) { | ||||||
|  |                     layoutManager.scrollToPosition(0) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun setupFabs() { |     private fun setupFabs() { | ||||||
| @ -205,6 +214,9 @@ class HomeRoomListFragment @Inject constructor( | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun setUpAdapters(sections: Set<HomeRoomSection>) { |     private fun setUpAdapters(sections: Set<HomeRoomSection>) { | ||||||
|  |         concatAdapter.adapters.forEach { | ||||||
|  |             concatAdapter.removeAdapter(it) | ||||||
|  |         } | ||||||
|         sections.forEach { |         sections.forEach { | ||||||
|             concatAdapter.addAdapter(getAdapterForData(it)) |             concatAdapter.addAdapter(getAdapterForData(it)) | ||||||
|         } |         } | ||||||
| @ -234,12 +246,11 @@ class HomeRoomListFragment @Inject constructor( | |||||||
|             is HomeRoomSection.RoomSummaryData -> { |             is HomeRoomSection.RoomSummaryData -> { | ||||||
|                 HomeFilteredRoomsController( |                 HomeFilteredRoomsController( | ||||||
|                         roomSummaryItemFactory, |                         roomSummaryItemFactory, | ||||||
|                         showFilters = section.showFilters, |  | ||||||
|                 ).also { controller -> |                 ).also { controller -> | ||||||
|                     controller.listener = this |                     controller.listener = this | ||||||
|                     controller.onFilterChanged = ::onRoomFilterChanged |                     controller.onFilterChanged = ::onRoomFilterChanged | ||||||
|                     section.filtersData.onEach { |                     section.filtersData.onEach { | ||||||
|                         controller.submitFiltersData(it) |                         controller.submitFiltersData(it.getOrNull()) | ||||||
|                     }.launchIn(lifecycleScope) |                     }.launchIn(lifecycleScope) | ||||||
|                     section.list.observe(viewLifecycleOwner) { list -> |                     section.list.observe(viewLifecycleOwner) { list -> | ||||||
|                         controller.submitList(list) |                         controller.submitList(list) | ||||||
|  | |||||||
| @ -34,6 +34,7 @@ import kotlinx.coroutines.flow.SharedFlow | |||||||
| import kotlinx.coroutines.flow.asSharedFlow | import kotlinx.coroutines.flow.asSharedFlow | ||||||
| import kotlinx.coroutines.flow.combine | import kotlinx.coroutines.flow.combine | ||||||
| import kotlinx.coroutines.flow.distinctUntilChanged | import kotlinx.coroutines.flow.distinctUntilChanged | ||||||
|  | import kotlinx.coroutines.flow.first | ||||||
| import kotlinx.coroutines.flow.launchIn | import kotlinx.coroutines.flow.launchIn | ||||||
| import kotlinx.coroutines.flow.map | import kotlinx.coroutines.flow.map | ||||||
| import kotlinx.coroutines.flow.onEach | import kotlinx.coroutines.flow.onEach | ||||||
| @ -53,12 +54,14 @@ import org.matrix.android.sdk.api.session.room.model.Membership | |||||||
| import org.matrix.android.sdk.api.session.room.model.tag.RoomTag | import org.matrix.android.sdk.api.session.room.model.tag.RoomTag | ||||||
| import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams | import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams | ||||||
| import org.matrix.android.sdk.api.session.room.state.isPublic | import org.matrix.android.sdk.api.session.room.state.isPublic | ||||||
|  | import org.matrix.android.sdk.api.util.Optional | ||||||
| import org.matrix.android.sdk.flow.flow | import org.matrix.android.sdk.flow.flow | ||||||
| 
 | 
 | ||||||
| class HomeRoomListViewModel @AssistedInject constructor( | class HomeRoomListViewModel @AssistedInject constructor( | ||||||
|         @Assisted initialState: HomeRoomListViewState, |         @Assisted initialState: HomeRoomListViewState, | ||||||
|         private val session: Session, |         private val session: Session, | ||||||
|         private val spaceStateHandler: SpaceStateHandler, |         private val spaceStateHandler: SpaceStateHandler, | ||||||
|  |         private val preferencesStore: HomeLayoutPreferencesStore, | ||||||
| ) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) { | ) : VectorViewModel<HomeRoomListViewState, HomeRoomListAction, HomeRoomListViewEvents>(initialState) { | ||||||
| 
 | 
 | ||||||
|     @AssistedFactory |     @AssistedFactory | ||||||
| @ -82,17 +85,30 @@ class HomeRoomListViewModel @AssistedInject constructor( | |||||||
| 
 | 
 | ||||||
|     init { |     init { | ||||||
|         configureSections() |         configureSections() | ||||||
|  |         observePreferences() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun configureSections() { |     private fun observePreferences() { | ||||||
|  |         preferencesStore.areRecentsEnabledFlow.onEach { | ||||||
|  |             configureSections() | ||||||
|  |         }.launchIn(viewModelScope) | ||||||
|  | 
 | ||||||
|  |         preferencesStore.isAZOrderingEnabledFlow.onEach { | ||||||
|  |             configureSections() | ||||||
|  |         }.launchIn(viewModelScope) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun configureSections() = viewModelScope.launch { | ||||||
|         val newSections = mutableSetOf<HomeRoomSection>() |         val newSections = mutableSetOf<HomeRoomSection>() | ||||||
| 
 | 
 | ||||||
|         newSections.add(getRecentRoomsSection()) |         val areSettingsEnabled = preferencesStore.areRecentsEnabledFlow.first() | ||||||
|  | 
 | ||||||
|  |         if (areSettingsEnabled) { | ||||||
|  |             newSections.add(getRecentRoomsSection()) | ||||||
|  |         } | ||||||
|         newSections.add(getFilteredRoomsSection()) |         newSections.add(getFilteredRoomsSection()) | ||||||
| 
 | 
 | ||||||
|         viewModelScope.launch { |         _sections.emit(newSections) | ||||||
|             _sections.emit(newSections) |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         setState { |         setState { | ||||||
|             copy(state = StateView.State.Content) |             copy(state = StateView.State.Content) | ||||||
| @ -111,13 +127,17 @@ class HomeRoomListViewModel @AssistedInject constructor( | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun getFilteredRoomsSection(): HomeRoomSection.RoomSummaryData { |     private suspend fun getFilteredRoomsSection(): HomeRoomSection.RoomSummaryData { | ||||||
|         val builder = RoomSummaryQueryParams.Builder().also { |         val builder = RoomSummaryQueryParams.Builder().also { | ||||||
|             it.memberships = listOf(Membership.JOIN) |             it.memberships = listOf(Membership.JOIN) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         val params = getFilteredQueryParams(HomeRoomFilter.ALL, builder.build()) |         val params = getFilteredQueryParams(HomeRoomFilter.ALL, builder.build()) | ||||||
|         val sortOrder = RoomSortOrder.ACTIVITY // #6506 |         val sortOrder = if (preferencesStore.isAZOrderingEnabledFlow.first()) { | ||||||
|  |             RoomSortOrder.NAME | ||||||
|  |         } else { | ||||||
|  |             RoomSortOrder.ACTIVITY | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         val liveResults = session.roomService().getFilteredPagedRoomSummariesLive( |         val liveResults = session.roomService().getFilteredPagedRoomSummariesLive( | ||||||
|                 params, |                 params, | ||||||
| @ -135,19 +155,18 @@ class HomeRoomListViewModel @AssistedInject constructor( | |||||||
|                 .onEach { selectedSpaceOption -> |                 .onEach { selectedSpaceOption -> | ||||||
|                     val selectedSpace = selectedSpaceOption.orNull() |                     val selectedSpace = selectedSpaceOption.orNull() | ||||||
|                     liveResults.queryParams = liveResults.queryParams.copy( |                     liveResults.queryParams = liveResults.queryParams.copy( | ||||||
|                             spaceFilter =  selectedSpace?.roomId.toActiveSpaceOrNoFilter() |                             spaceFilter = selectedSpace?.roomId.toActiveSpaceOrNoFilter() | ||||||
|                     ) |                     ) | ||||||
|                 }.launchIn(viewModelScope) |                 }.launchIn(viewModelScope) | ||||||
| 
 | 
 | ||||||
|         return HomeRoomSection.RoomSummaryData( |         return HomeRoomSection.RoomSummaryData( | ||||||
|                 list = liveResults.livePagedList, |                 list = liveResults.livePagedList, | ||||||
|                 showFilters = true, // #6506 |  | ||||||
|                 filtersData = getFiltersDataFlow() |                 filtersData = getFiltersDataFlow() | ||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun getFiltersDataFlow(): SharedFlow<List<HomeRoomFilter>> { |     private fun getFiltersDataFlow(): SharedFlow<Optional<List<HomeRoomFilter>>> { | ||||||
|         val flow = MutableSharedFlow<List<HomeRoomFilter>>(replay = 1) |         val flow = MutableSharedFlow<Optional<List<HomeRoomFilter>>>(replay = 1) | ||||||
| 
 | 
 | ||||||
|         val favouritesFlow = session.flow() |         val favouritesFlow = session.flow() | ||||||
|                 .liveRoomSummaries( |                 .liveRoomSummaries( | ||||||
| @ -168,25 +187,28 @@ class HomeRoomListViewModel @AssistedInject constructor( | |||||||
|                 .map { it.isNotEmpty() } |                 .map { it.isNotEmpty() } | ||||||
|                 .distinctUntilChanged() |                 .distinctUntilChanged() | ||||||
| 
 | 
 | ||||||
|         favouritesFlow.combine(dmsFLow) { hasFavourite, hasDm -> |         combine(favouritesFlow, dmsFLow, preferencesStore.areFiltersEnabledFlow) { hasFavourite, hasDm, areFiltersEnabled -> | ||||||
|             hasFavourite to hasDm |             Triple(hasFavourite, hasDm, areFiltersEnabled) | ||||||
|         }.onEach { (hasFavourite, hasDm) -> |         }.onEach { (hasFavourite, hasDm, areFiltersEnabled) -> | ||||||
|             val filtersData = mutableListOf( |             if (areFiltersEnabled) { | ||||||
|                     HomeRoomFilter.ALL, |                 val filtersData = mutableListOf( | ||||||
|                     HomeRoomFilter.UNREADS |                         HomeRoomFilter.ALL, | ||||||
|             ) |                         HomeRoomFilter.UNREADS | ||||||
|             if (hasFavourite) { |  | ||||||
|                 filtersData.add( |  | ||||||
|                         HomeRoomFilter.FAVOURITES |  | ||||||
|                 ) |                 ) | ||||||
|  |                 if (hasFavourite) { | ||||||
|  |                     filtersData.add( | ||||||
|  |                             HomeRoomFilter.FAVOURITES | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 if (hasDm) { | ||||||
|  |                     filtersData.add( | ||||||
|  |                             HomeRoomFilter.PEOPlE | ||||||
|  |                     ) | ||||||
|  |                 } | ||||||
|  |                 flow.emit(Optional.from(filtersData)) | ||||||
|  |             } else { | ||||||
|  |                 flow.emit(Optional.empty()) | ||||||
|             } |             } | ||||||
|             if (hasDm) { |  | ||||||
|                 filtersData.add( |  | ||||||
|                         HomeRoomFilter.PEOPlE |  | ||||||
|                 ) |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             flow.emit(filtersData) |  | ||||||
|         }.launchIn(viewModelScope) |         }.launchIn(viewModelScope) | ||||||
| 
 | 
 | ||||||
|         return flow |         return flow | ||||||
|  | |||||||
| @ -21,12 +21,12 @@ import androidx.paging.PagedList | |||||||
| import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter | import im.vector.app.features.home.room.list.home.filter.HomeRoomFilter | ||||||
| import kotlinx.coroutines.flow.SharedFlow | import kotlinx.coroutines.flow.SharedFlow | ||||||
| import org.matrix.android.sdk.api.session.room.model.RoomSummary | import org.matrix.android.sdk.api.session.room.model.RoomSummary | ||||||
|  | import org.matrix.android.sdk.api.util.Optional | ||||||
| 
 | 
 | ||||||
| sealed class HomeRoomSection { | sealed class HomeRoomSection { | ||||||
|     data class RoomSummaryData( |     data class RoomSummaryData( | ||||||
|             val list: LiveData<PagedList<RoomSummary>>, |             val list: LiveData<PagedList<RoomSummary>>, | ||||||
|             val showFilters: Boolean, |             val filtersData: SharedFlow<Optional<List<HomeRoomFilter>>>, | ||||||
|             val filtersData: SharedFlow<List<HomeRoomFilter>> |  | ||||||
|     ) : HomeRoomSection() |     ) : HomeRoomSection() | ||||||
| 
 | 
 | ||||||
|     data class RecentRoomsData( |     data class RecentRoomsData( | ||||||
|  | |||||||
| @ -28,7 +28,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary | |||||||
| 
 | 
 | ||||||
| class HomeFilteredRoomsController( | class HomeFilteredRoomsController( | ||||||
|         private val roomSummaryItemFactory: RoomSummaryItemFactory, |         private val roomSummaryItemFactory: RoomSummaryItemFactory, | ||||||
|         private val showFilters: Boolean, |  | ||||||
| ) : PagedListEpoxyController<RoomSummary>( | ) : PagedListEpoxyController<RoomSummary>( | ||||||
|         // Important it must match the PageList builder notify Looper |         // Important it must match the PageList builder notify Looper | ||||||
|         modelBuildingHandler = createUIHandler() |         modelBuildingHandler = createUIHandler() | ||||||
| @ -48,7 +47,7 @@ class HomeFilteredRoomsController( | |||||||
| 
 | 
 | ||||||
|     override fun addModels(models: List<EpoxyModel<*>>) { |     override fun addModels(models: List<EpoxyModel<*>>) { | ||||||
|         val host = this |         val host = this | ||||||
|         if (showFilters) { |         if (host.filtersData != null) { | ||||||
|             roomFilterHeaderItem { |             roomFilterHeaderItem { | ||||||
|                 id("filter_header") |                 id("filter_header") | ||||||
|                 filtersData(host.filtersData) |                 filtersData(host.filtersData) | ||||||
| @ -58,7 +57,7 @@ class HomeFilteredRoomsController( | |||||||
|         super.addModels(models) |         super.addModels(models) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fun submitFiltersData(data: List<HomeRoomFilter>) { |     fun submitFiltersData(data: List<HomeRoomFilter>?) { | ||||||
|         this.filtersData = data |         this.filtersData = data | ||||||
|         requestForcedModelBuild() |         requestForcedModelBuild() | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -0,0 +1,78 @@ | |||||||
|  | /* | ||||||
|  |  * Copyright (c) 2022 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.app.features.home.room.list.home.layout | ||||||
|  | 
 | ||||||
|  | import android.os.Bundle | ||||||
|  | import android.view.LayoutInflater | ||||||
|  | import android.view.View | ||||||
|  | import android.view.ViewGroup | ||||||
|  | import androidx.lifecycle.lifecycleScope | ||||||
|  | import dagger.hilt.android.AndroidEntryPoint | ||||||
|  | import im.vector.app.R | ||||||
|  | import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment | ||||||
|  | import im.vector.app.databinding.BottomSheetHomeLayoutSettingsBinding | ||||||
|  | import im.vector.app.features.home.room.list.home.HomeLayoutPreferencesStore | ||||||
|  | import kotlinx.coroutines.flow.first | ||||||
|  | import kotlinx.coroutines.launch | ||||||
|  | import javax.inject.Inject | ||||||
|  | 
 | ||||||
|  | @AndroidEntryPoint | ||||||
|  | class HomeLayoutSettingBottomDialogFragment : VectorBaseBottomSheetDialogFragment<BottomSheetHomeLayoutSettingsBinding>() { | ||||||
|  | 
 | ||||||
|  |     @Inject lateinit var preferencesStore: HomeLayoutPreferencesStore | ||||||
|  | 
 | ||||||
|  |     override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetHomeLayoutSettingsBinding { | ||||||
|  |         return BottomSheetHomeLayoutSettingsBinding.inflate(inflater, container, false) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||||||
|  |         super.onViewCreated(view, savedInstanceState) | ||||||
|  | 
 | ||||||
|  |         viewLifecycleOwner.lifecycleScope.launch { | ||||||
|  |             views.homeLayoutSettingsRecents.isChecked = preferencesStore.areRecentsEnabledFlow.first() | ||||||
|  |             views.homeLayoutSettingsFilters.isChecked = preferencesStore.areFiltersEnabledFlow.first() | ||||||
|  | 
 | ||||||
|  |             if (preferencesStore.isAZOrderingEnabledFlow.first()) { | ||||||
|  |                 views.homeLayoutSettingsSortName.isChecked = true | ||||||
|  |             } else { | ||||||
|  |                 views.homeLayoutSettingsSortActivity.isChecked = true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         views.homeLayoutSettingsRecents.setOnCheckedChangeListener { _, isChecked -> | ||||||
|  |             setRecentsEnabled(isChecked) | ||||||
|  |         } | ||||||
|  |         views.homeLayoutSettingsFilters.setOnCheckedChangeListener { _, isChecked -> | ||||||
|  |             setFiltersEnabled(isChecked) | ||||||
|  |         } | ||||||
|  |         views.homeLayoutSettingsSortGroup.setOnCheckedChangeListener { _, checkedId -> | ||||||
|  |             setAzOrderingEnabled(checkedId == R.id.home_layout_settings_sort_name) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun setRecentsEnabled(isEnabled: Boolean) = lifecycleScope.launch { | ||||||
|  |         preferencesStore.setRecentsEnabled(isEnabled) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun setFiltersEnabled(isEnabled: Boolean) = lifecycleScope.launch { | ||||||
|  |         preferencesStore.setFiltersEnabled(isEnabled) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun setAzOrderingEnabled(isEnabled: Boolean) = lifecycleScope.launch { | ||||||
|  |         preferencesStore.setAZOrderingEnabled(isEnabled) | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -59,7 +59,13 @@ class RecentRoomCarouselController @Inject constructor( | |||||||
|         data?.let { data -> |         data?.let { data -> | ||||||
|             carousel { |             carousel { | ||||||
|                 id("recents_carousel") |                 id("recents_carousel") | ||||||
|                 padding(Carousel.Padding(host.hPadding, host.itemSpacing)) |                 padding(Carousel.Padding( | ||||||
|  |                         host.hPadding, | ||||||
|  |                         0, | ||||||
|  |                         host.hPadding, | ||||||
|  |                         0, | ||||||
|  |                         host.itemSpacing) | ||||||
|  |                 ) | ||||||
|                 withModelsFrom(data) { roomSummary -> |                 withModelsFrom(data) { roomSummary -> | ||||||
|                     val onClick = host.listener?.let { it::onRoomClicked } |                     val onClick = host.listener?.let { it::onRoomClicked } | ||||||
|                     val onLongClick = host.listener?.let { it::onRoomLongClicked } |                     val onLongClick = host.listener?.let { it::onRoomLongClicked } | ||||||
|  | |||||||
| @ -0,0 +1,67 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|  |     android:id="@+id/rootLayout" | ||||||
|  |     android:layout_width="match_parent" | ||||||
|  |     android:layout_height="wrap_content" | ||||||
|  |     android:background="?colorSurface" | ||||||
|  |     android:orientation="vertical"> | ||||||
|  | 
 | ||||||
|  |     <TextView | ||||||
|  |         style="@style/Widget.Vector.TextView.Subtitle" | ||||||
|  |         android:layout_width="wrap_content" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:layout_marginHorizontal="16dp" | ||||||
|  |         android:layout_marginTop="16dp" | ||||||
|  |         android:layout_marginBottom="8dp" | ||||||
|  |         android:text="@string/home_layout_preferences" | ||||||
|  |         android:textAllCaps="true" /> | ||||||
|  | 
 | ||||||
|  |     <com.google.android.material.switchmaterial.SwitchMaterial | ||||||
|  |         android:id="@+id/home_layout_settings_recents" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="64dp" | ||||||
|  |         android:layout_marginHorizontal="16dp" | ||||||
|  |         android:checked="true" | ||||||
|  |         android:text="@string/home_layout_preferences_recents" /> | ||||||
|  | 
 | ||||||
|  |     <com.google.android.material.switchmaterial.SwitchMaterial | ||||||
|  |         android:id="@+id/home_layout_settings_filters" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="64dp" | ||||||
|  |         android:layout_marginHorizontal="16dp" | ||||||
|  |         android:checked="true" | ||||||
|  |         android:text="@string/home_layout_preferences_filters" /> | ||||||
|  | 
 | ||||||
|  |     <TextView | ||||||
|  |         style="@style/Widget.Vector.TextView.Subtitle" | ||||||
|  |         android:layout_width="wrap_content" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:layout_marginHorizontal="16dp" | ||||||
|  |         android:layout_marginVertical="8dp" | ||||||
|  |         android:text="@string/home_layout_preferences_sort_by" | ||||||
|  |         android:textAllCaps="true" /> | ||||||
|  | 
 | ||||||
|  |     <RadioGroup | ||||||
|  |         android:id="@+id/home_layout_settings_sort_group" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="wrap_content" | ||||||
|  |         android:layout_marginHorizontal="16dp" | ||||||
|  |         android:orientation="vertical"> | ||||||
|  | 
 | ||||||
|  |         <RadioButton | ||||||
|  |             android:id="@+id/home_layout_settings_sort_activity" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:checked="true" | ||||||
|  |             android:text="@string/home_layout_preferences_sort_activity" | ||||||
|  |             android:textColor="?vctr_content_primary" /> | ||||||
|  | 
 | ||||||
|  |         <RadioButton | ||||||
|  |             android:id="@+id/home_layout_settings_sort_name" | ||||||
|  |             android:layout_width="wrap_content" | ||||||
|  |             android:layout_height="wrap_content" | ||||||
|  |             android:text="@string/home_layout_preferences_sort_name" | ||||||
|  |             android:textColor="?vctr_content_primary" /> | ||||||
|  |     </RadioGroup> | ||||||
|  | 
 | ||||||
|  | </LinearLayout> | ||||||
| @ -3,6 +3,10 @@ | |||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     xmlns:tools="http://schemas.android.com/tools"> |     xmlns:tools="http://schemas.android.com/tools"> | ||||||
| 
 | 
 | ||||||
|  |     <item | ||||||
|  |         android:id="@+id/menu_home_layout_settings" | ||||||
|  |         android:title="@string/home_layout_preferences"/> | ||||||
|  | 
 | ||||||
|     <item |     <item | ||||||
|         android:id="@+id/menu_home_invite_friends" |         android:id="@+id/menu_home_invite_friends" | ||||||
|         android:title="@string/invite_friends" |         android:title="@string/invite_friends" | ||||||
| @ -37,6 +41,6 @@ | |||||||
|         android:icon="@drawable/ic_home_search" |         android:icon="@drawable/ic_home_search" | ||||||
|         android:title="@string/home_filter_placeholder_home" |         android:title="@string/home_filter_placeholder_home" | ||||||
|         app:iconTint="?vctr_content_secondary" |         app:iconTint="?vctr_content_secondary" | ||||||
|         app:showAsAction="always" /> |         app:showAsAction="ifRoom" /> | ||||||
| 
 | 
 | ||||||
| </menu> | </menu> | ||||||
|  | |||||||
| @ -427,6 +427,15 @@ | |||||||
| 
 | 
 | ||||||
|     <!-- Home screen --> |     <!-- Home screen --> | ||||||
|     <string name="home_filter_placeholder_home">Filter room names</string> |     <string name="home_filter_placeholder_home">Filter room names</string> | ||||||
|  |     <string name="home_layout_preferences">Layout preferences</string> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     <!-- Home screen layout settings --> | ||||||
|  |     <string name="home_layout_preferences_filters">Show filters</string> | ||||||
|  |     <string name="home_layout_preferences_recents">Show recents</string> | ||||||
|  |     <string name="home_layout_preferences_sort_by">Sort by</string> | ||||||
|  |     <string name="home_layout_preferences_sort_activity">Activity</string> | ||||||
|  |     <string name="home_layout_preferences_sort_name">A - Z</string> | ||||||
| 
 | 
 | ||||||
|     <!-- Home fragment --> |     <!-- Home fragment --> | ||||||
|     <string name="invitations_header">Invites</string> |     <string name="invitations_header">Invites</string> | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user