Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Space List Bottom Sheet #6749

Merged
merged 24 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ab4eda1
Adds SpacesBottomSheet
ericdecanini Aug 2, 2022
55d8b6a
Merge remote-tracking branch 'origin/develop' into feature/eric/space…
ericdecanini Aug 2, 2022
aa24deb
Adds new space list controller
ericdecanini Aug 2, 2022
5d18365
Fixes bug where bottom sheet sometimes renders with the wrong height
ericdecanini Aug 3, 2022
b4ed380
Finalises home and add bottom sheet buttons
ericdecanini Aug 3, 2022
79e6dd0
Makes bottom sheet dismiss on space change
ericdecanini Aug 4, 2022
ff71e69
Makes space list work inside spaces
ericdecanini Aug 5, 2022
0506c9a
Fixes bottom sheet intermittently not having the correct height
ericdecanini Aug 5, 2022
a821f34
Adds drag and drop to space list
ericdecanini Aug 5, 2022
90f2b93
Appends to comment in SpaceListFragment and refactors SpaceListBottom…
ericdecanini Aug 5, 2022
0567fa3
Changes header text of bottom sheet to Change Space
ericdecanini Aug 5, 2022
e6508e8
Cleans up epoxy class for NewSpaceSummaryItem and adds ellipsize to h…
ericdecanini Aug 5, 2022
41d859d
Merge remote-tracking branch 'origin/develop' into feature/eric/space…
ericdecanini Aug 5, 2022
1ffa02c
Merge remote-tracking branch 'origin/feature/eric/new_fab' into featu…
ericdecanini Aug 5, 2022
7565707
Adds changelog file
ericdecanini Aug 5, 2022
7b61460
Merge branch 'feature/eric/new_fab' into feature/eric/space-list-modal
ericdecanini Aug 9, 2022
9892c66
Fixes lint errors
ericdecanini Aug 9, 2022
65b7a31
Fixes toMvRxBundle import
ericdecanini Aug 9, 2022
f94aad6
Merge branch 'feature/eric/new_fab' into feature/eric/space-list-modal
ericdecanini Aug 9, 2022
ddaf539
Removes params passed into HomeRoomListFragment and fixes lint error
ericdecanini Aug 10, 2022
e87eefb
Merge remote-tracking branch 'origin/develop' into feature/eric/space…
ericdecanini Aug 10, 2022
358ec5a
Fixes post merge errors
ericdecanini Aug 10, 2022
fd37b31
Changes changelog file extension
ericdecanini Aug 10, 2022
8b0fba2
Merge remote-tracking branch 'origin/develop' into feature/eric/space…
ericdecanini Aug 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/6749.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Adds space list bottom sheet for new app layout
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to provide changelog for features which are not accessible yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should them but they should be .wip

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to provide changelogs for features, which are not accessible for users 🤔

6 changes: 6 additions & 0 deletions vector/src/main/java/im/vector/app/core/di/ViewModelModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import im.vector.app.features.home.HomeSharedActionViewModel
import im.vector.app.features.home.room.detail.RoomDetailSharedActionViewModel
import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
import im.vector.app.features.home.room.list.actions.RoomListSharedActionViewModel
import im.vector.app.features.reactions.EmojiChooserViewModel
import im.vector.app.features.roomdirectory.RoomDirectorySharedActionViewModel
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
Expand Down Expand Up @@ -157,4 +158,9 @@ interface ViewModelModule {
@IntoMap
@ViewModelKey(SpacePeopleSharedActionViewModel::class)
fun bindSpacePeopleSharedActionViewModel(viewModel: SpacePeopleSharedActionViewModel): ViewModel

@Binds
@IntoMap
@ViewModelKey(RoomListSharedActionViewModel::class)
fun bindRoomListSharedActionViewModel(viewModel: RoomListSharedActionViewModel): ViewModel
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import im.vector.app.features.themes.ThemeUtils
@EpoxyModelClass
abstract class HomeSpaceSummaryItem : VectorEpoxyModel<HomeSpaceSummaryItem.Holder>(R.layout.item_space) {

@EpoxyAttribute var text: String = ""
@EpoxyAttribute var selected: Boolean = false
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
@EpoxyAttribute var countState: UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* 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.app.features.grouplist

import android.content.res.ColorStateList
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.VectorEpoxyModel
import im.vector.app.core.epoxy.onClick
import im.vector.app.core.platform.CheckableConstraintLayout
import im.vector.app.features.home.room.list.UnreadCounterBadgeView
import im.vector.app.features.themes.ThemeUtils

@EpoxyModelClass
abstract class NewHomeSpaceSummaryItem : VectorEpoxyModel<NewHomeSpaceSummaryItem.Holder>(R.layout.item_new_space) {

@EpoxyAttribute var text: String = ""
@EpoxyAttribute var selected: Boolean = false
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
@EpoxyAttribute var countState: UnreadCounterBadgeView.State = UnreadCounterBadgeView.State(0, false)
@EpoxyAttribute var showSeparator: Boolean = false

override fun getViewType() = R.id.space_item_home

override fun bind(holder: Holder) {
super.bind(holder)
holder.root.onClick(listener)
holder.name.text = holder.view.context.getString(R.string.all_chats)
holder.root.isChecked = selected
holder.root.context.resources
holder.avatar.background = ContextCompat.getDrawable(holder.view.context, R.drawable.new_space_home_background)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't it better to set it in xml?

Copy link
Contributor Author

@ericdecanini ericdecanini Aug 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because we use the same XML for NewSpaceSummaryItem where we don't want to have this background

holder.avatar.backgroundTintList = ColorStateList.valueOf(
ColorUtils.setAlphaComponent(ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_tertiary), (255 * 0.3).toInt()))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to move to xml resource, both declaration of color state and setting it as backgroundTintList

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

holder.avatar.setImageResource(R.drawable.ic_space_home)
holder.avatar.imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_primary))
holder.avatar.scaleType = ImageView.ScaleType.CENTER_INSIDE

holder.unreadCounter.render(countState)
}

class Holder : VectorEpoxyHolder() {
val root by bind<CheckableConstraintLayout>(R.id.root)
val avatar by bind<ImageView>(R.id.avatar)
val name by bind<TextView>(R.id.name)
val unreadCounter by bind<UnreadCounterBadgeView>(R.id.unread_counter)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import im.vector.app.features.call.SharedKnownCallsViewModel
import im.vector.app.features.call.VectorCallActivity
import im.vector.app.features.call.dialpad.DialPadFragment
import im.vector.app.features.call.webrtc.WebRtcCallManager
import im.vector.app.features.home.room.list.RoomListParams
import im.vector.app.features.home.room.list.home.HomeRoomListFragment
import im.vector.app.features.popup.PopupAlertManager
import im.vector.app.features.popup.VerificationVectorAlert
Expand All @@ -67,7 +68,7 @@ class NewHomeDetailFragment @Inject constructor(
private val alertManager: PopupAlertManager,
private val callManager: WebRtcCallManager,
private val vectorPreferences: VectorPreferences,
private val appStateHandler: SpaceStateHandler,
private val spaceStateHandler: SpaceStateHandler,
private val session: Session,
) : VectorBaseFragment<FragmentNewHomeDetailBinding>(),
KeysBackupBanner.Delegate,
Expand Down Expand Up @@ -176,13 +177,13 @@ class NewHomeDetailFragment @Inject constructor(
}

private fun navigateBack() {
val previousSpaceId = appStateHandler.getSpaceBackstack().removeLastOrNull()
val parentSpaceId = appStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull()
val previousSpaceId = spaceStateHandler.getSpaceBackstack().removeLastOrNull()
val parentSpaceId = spaceStateHandler.getCurrentSpace()?.flattenParentIds?.lastOrNull()
setCurrentSpace(previousSpaceId ?: parentSpaceId)
}

private fun setCurrentSpace(spaceId: String?) {
appStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false)
spaceStateHandler.setCurrentSpace(spaceId, isForwardNavigation = false)
sharedActionViewModel.post(HomeActivitySharedAction.OnCloseSpace)
}

Expand All @@ -205,7 +206,7 @@ class NewHomeDetailFragment @Inject constructor(
}

private fun refreshSpaceState() {
appStateHandler.getCurrentSpace()?.let {
spaceStateHandler.getCurrentSpace()?.let {
onSpaceChange(it)
}
}
Expand Down Expand Up @@ -337,7 +338,8 @@ class NewHomeDetailFragment @Inject constructor(
if (fragmentToShow == null) {
when (tab) {
is HomeTab.RoomList -> {
add(R.id.roomListContainer, HomeRoomListFragment::class.java, null, fragmentTag)
val params = RoomListParams(tab.displayMode)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we don't need any param for HomeRoomListFragment

add(R.id.roomListContainer, HomeRoomListFragment::class.java, params.toMvRxBundle(), fragmentTag)
}
is HomeTab.DialPad -> {
add(R.id.roomListContainer, createDialPadFragment(), fragmentTag)
Expand Down Expand Up @@ -450,7 +452,7 @@ class NewHomeDetailFragment @Inject constructor(
return this
}

override fun onBackPressed(toolbarButton: Boolean) = if (appStateHandler.getCurrentSpace() != null) {
override fun onBackPressed(toolbarButton: Boolean) = if (spaceStateHandler.getCurrentSpace() != null) {
navigateBack()
true
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ sealed class RoomListQuickActionsSharedAction(
@StringRes val titleRes: Int,
@DrawableRes val iconResId: Int?,
val destructive: Boolean = false
) :
VectorSharedAction {
) : VectorSharedAction {

data class NotificationsAllNoisy(val roomId: String) : RoomListQuickActionsSharedAction(
R.string.room_list_quick_actions_notifications_all_noisy,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.actions

import im.vector.app.core.platform.VectorSharedAction

sealed class RoomListSharedAction : VectorSharedAction {

object CloseBottomSheet : RoomListSharedAction()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.actions

import im.vector.app.core.platform.VectorSharedActionViewModel
import javax.inject.Inject

class RoomListSharedActionViewModel @Inject constructor() : VectorSharedActionViewModel<RoomListSharedAction>()
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import im.vector.app.features.home.room.list.RoomSummaryPagedController
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
import im.vector.app.features.home.room.list.actions.RoomListSharedAction
import im.vector.app.features.home.room.list.actions.RoomListSharedActionViewModel
import im.vector.app.features.spaces.SpaceListBottomSheet
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.matrix.android.sdk.api.session.room.model.RoomSummary
Expand All @@ -59,10 +62,13 @@ class HomeRoomListFragment @Inject constructor(
RoomListListener {

private val roomListViewModel: HomeRoomListViewModel by fragmentViewModel()
private lateinit var sharedActionViewModel: RoomListQuickActionsSharedActionViewModel
private lateinit var sharedQuickActionsViewModel: RoomListQuickActionsSharedActionViewModel
private lateinit var sharedActionViewModel: RoomListSharedActionViewModel
private var concatAdapter = ConcatAdapter()
private var modelBuildListener: OnModelBuildFinishedListener? = null

private val spaceListBottomSheet = SpaceListBottomSheet()

private lateinit var stateRestorer: LayoutManagerStateRestorer

override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomListBinding {
Expand All @@ -71,15 +77,25 @@ class HomeRoomListFragment @Inject constructor(

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
views.stateView.contentView = views.roomListView
views.stateView.state = StateView.State.Loading
setupObservers()
setupRecyclerView()
setupFabs()
}

private fun setupObservers() {
sharedQuickActionsViewModel = activityViewModelProvider[RoomListQuickActionsSharedActionViewModel::class.java]
sharedActionViewModel = activityViewModelProvider[RoomListSharedActionViewModel::class.java]

sharedActionViewModel = activityViewModelProvider[RoomListQuickActionsSharedActionViewModel::class.java]
sharedActionViewModel
.stream()
.onEach { handleQuickActions(it) }
.onEach(::handleSharedAction)
.launchIn(viewLifecycleOwner.lifecycleScope)
sharedQuickActionsViewModel
.stream()
.onEach(::handleQuickActions)
.launchIn(viewLifecycleOwner.lifecycleScope)

views.stateView.contentView = views.roomListView
views.stateView.state = StateView.State.Loading

roomListViewModel.observeViewEvents {
when (it) {
Expand All @@ -89,9 +105,42 @@ class HomeRoomListFragment @Inject constructor(
is HomeRoomListViewEvents.Done -> Unit
}
}
}

setupRecyclerView()
setupFabs()
private fun handleSharedAction(action: RoomListSharedAction) {
when (action) {
RoomListSharedAction.CloseBottomSheet -> spaceListBottomSheet.dismiss()
}
}

private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
when (quickAction) {
is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY))
}
is RoomListQuickActionsSharedAction.NotificationsAll -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES))
}
is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY))
}
is RoomListQuickActionsSharedAction.NotificationsMute -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE))
}
is RoomListQuickActionsSharedAction.Settings -> {
navigator.openRoomProfile(requireActivity(), quickAction.roomId)
}
is RoomListQuickActionsSharedAction.Favorite -> {
roomListViewModel.handle(HomeRoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_FAVOURITE))
}
is RoomListQuickActionsSharedAction.LowPriority -> {
roomListViewModel.handle(HomeRoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY))
}
is RoomListQuickActionsSharedAction.Leave -> {
roomListViewModel.handle(HomeRoomListAction.LeaveRoom(quickAction.roomId))
promptLeaveRoom(quickAction.roomId)
}
}
}

private fun setupRecyclerView() {
Expand All @@ -118,7 +167,8 @@ class HomeRoomListFragment @Inject constructor(
}

views.newLayoutOpenSpacesButton.setOnClickListener {
// Click action for open spaces modal goes here (Issue #6499)
// Click action for open spaces modal goes here
spaceListBottomSheet.show(requireActivity().supportFragmentManager, SpaceListBottomSheet.TAG)
}

// Hide FABs when list is scrolling
Expand Down Expand Up @@ -155,35 +205,6 @@ class HomeRoomListFragment @Inject constructor(
}
}

private fun handleQuickActions(quickAction: RoomListQuickActionsSharedAction) {
when (quickAction) {
is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES_NOISY))
}
is RoomListQuickActionsSharedAction.NotificationsAll -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.ALL_MESSAGES))
}
is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MENTIONS_ONLY))
}
is RoomListQuickActionsSharedAction.NotificationsMute -> {
roomListViewModel.handle(HomeRoomListAction.ChangeRoomNotificationState(quickAction.roomId, RoomNotificationState.MUTE))
}
is RoomListQuickActionsSharedAction.Settings -> {
navigator.openRoomProfile(requireActivity(), quickAction.roomId)
}
is RoomListQuickActionsSharedAction.Favorite -> {
roomListViewModel.handle(HomeRoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_FAVOURITE))
}
is RoomListQuickActionsSharedAction.LowPriority -> {
roomListViewModel.handle(HomeRoomListAction.ToggleTag(quickAction.roomId, RoomTag.ROOM_TAG_LOW_PRIORITY))
}
is RoomListQuickActionsSharedAction.Leave -> {
roomListViewModel.handle(HomeRoomListAction.LeaveRoom(quickAction.roomId))
promptLeaveRoom(quickAction.roomId)
}
}
}

private fun promptLeaveRoom(roomId: String) {
val isPublicRoom = roomListViewModel.isPublicRoom(roomId)
Expand Down
Loading