Resurrect mark all as read

This commit is contained in:
Valere 2021-03-31 16:51:32 +02:00 committed by Benoit Marty
parent c23437d45a
commit b390980ca2
7 changed files with 62 additions and 49 deletions

View file

@ -20,4 +20,5 @@ import im.vector.app.core.platform.VectorViewModelAction
sealed class HomeDetailAction : VectorViewModelAction {
data class SwitchDisplayMode(val displayMode: RoomListDisplayMode) : HomeDetailAction()
object MarkAllRoomsRead : HomeDetailAction()
}

View file

@ -18,6 +18,8 @@ package im.vector.app.features.home
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
@ -33,8 +35,8 @@ import im.vector.app.core.platform.ToolbarConfigurable
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.ui.views.CurrentCallsView
import im.vector.app.core.ui.views.KnownCallsViewHolder
import im.vector.app.core.ui.views.KeysBackupBanner
import im.vector.app.core.ui.views.KnownCallsViewHolder
import im.vector.app.databinding.FragmentHomeDetailBinding
import im.vector.app.features.call.SharedKnownCallsViewModel
import im.vector.app.features.call.VectorCallActivity
@ -49,7 +51,6 @@ import im.vector.app.features.themes.ThemeUtils
import im.vector.app.features.workers.signout.BannerState
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
import org.matrix.android.sdk.api.session.group.model.GroupSummary
import org.matrix.android.sdk.api.util.toMatrixItem
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
@ -79,6 +80,32 @@ class HomeDetailFragment @Inject constructor(
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
private lateinit var sharedCallActionViewModel: SharedKnownCallsViewModel
private var hasUnreadRooms = false
set(value) {
if (value != field) {
field = value
invalidateOptionsMenu()
}
}
override fun getMenuRes() = R.menu.room_list
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_home_mark_all_as_read -> {
viewModel.handle(HomeDetailAction.MarkAllRoomsRead)
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onPrepareOptionsMenu(menu: Menu) {
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = hasUnreadRooms
super.onPrepareOptionsMenu(menu)
}
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentHomeDetailBinding {
return FragmentHomeDetailBinding.inflate(inflater, container, false)
}
@ -314,6 +341,8 @@ class HomeDetailFragment @Inject constructor(
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_rooms).render(it.notificationCountRooms, it.notificationHighlightRooms)
views.bottomNavigationView.getOrCreateBadge(R.id.bottom_action_notification).render(it.notificationCountCatchup, it.notificationHighlightCatchup)
views.syncStateView.render(it.syncState)
hasUnreadRooms = it.hasUnreadMessages
}
private fun BadgeDrawable.render(count: Int, highlight: Boolean) {

View file

@ -16,6 +16,7 @@
package im.vector.app.features.home
import androidx.lifecycle.viewModelScope
import com.airbnb.mvrx.FragmentViewModelContext
import com.airbnb.mvrx.MvRxViewModelFactory
import com.airbnb.mvrx.ViewModelContext
@ -28,12 +29,16 @@ import im.vector.app.core.platform.VectorViewModel
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.grouplist.SelectedGroupDataSource
import im.vector.app.features.ui.UiStateRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.room.RoomCategoryFilter
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams
import org.matrix.android.sdk.internal.util.awaitCallback
import org.matrix.android.sdk.rx.asObservable
import org.matrix.android.sdk.rx.rx
import timber.log.Timber
import java.util.concurrent.TimeUnit
/**
@ -77,6 +82,7 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
override fun handle(action: HomeDetailAction) {
when (action) {
is HomeDetailAction.SwitchDisplayMode -> handleSwitchDisplayMode(action)
HomeDetailAction.MarkAllRoomsRead -> handleMarkAllRoomsRead()
}
}
@ -92,6 +98,27 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
// PRIVATE METHODS *****************************************************************************
private fun handleMarkAllRoomsRead() = withState { _ ->
// questionable to use viewmodelscope
viewModelScope.launch(Dispatchers.Default) {
val roomIds = session.getRoomSummaries(
roomSummaryQueryParams {
this.memberships = listOf(Membership.JOIN)
this.roomCategoryFilter = RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS
}
).map {
it.roomId
}
try {
awaitCallback<Unit> {
session.markAllAsRead(roomIds, it)
}
} catch (failure: Throwable) {
Timber.d(failure, "Failed to mark all as read")
}
}
}
private fun observeSyncState() {
session.rx()
.liveSyncState()
@ -157,7 +184,8 @@ class HomeDetailViewModel @AssistedInject constructor(@Assisted initialState: Ho
notificationCountPeople = dmRooms.totalCount() + dmInvites,
notificationHighlightPeople = dmRooms.isHighlight() || dmInvites > 0,
notificationCountRooms = otherRooms.totalCount() + roomsInvite,
notificationHighlightRooms = otherRooms.isHighlight() || roomsInvite > 0
notificationHighlightRooms = otherRooms.isHighlight() || roomsInvite > 0,
hasUnreadMessages = dmRooms.totalCount() + otherRooms.totalCount() > 0
)
}
}

View file

@ -34,5 +34,6 @@ data class HomeDetailViewState(
val notificationHighlightPeople: Boolean = false,
val notificationCountRooms: Int = 0,
val notificationHighlightRooms: Boolean = false,
val hasUnreadMessages: Boolean = false,
val syncState: SyncState = SyncState.Idle
) : MvRxState

View file

@ -29,5 +29,4 @@ sealed class RoomListAction : VectorViewModelAction {
data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListAction()
data class ToggleTag(val roomId: String, val tag: String) : RoomListAction()
data class LeaveRoom(val roomId: String) : RoomListAction()
object MarkAllRoomsRead : RoomListAction()
}

View file

@ -20,8 +20,6 @@ import android.content.DialogInterface
import android.os.Bundle
import android.os.Parcelable
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
@ -84,8 +82,6 @@ class RoomListFragment @Inject constructor(
return FragmentRoomListBinding.inflate(inflater, container, false)
}
private var hasUnreadRooms = false
data class SectionKey(
val name: String,
val isExpanded: Boolean
@ -100,24 +96,6 @@ class RoomListFragment @Inject constructor(
private val adapterInfosList = mutableListOf<SectionAdapterInfo>()
private var concatAdapter: ConcatAdapter? = null
override fun getMenuRes() = R.menu.room_list
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_home_mark_all_as_read -> {
roomListViewModel.handle(RoomListAction.MarkAllRoomsRead)
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onPrepareOptionsMenu(menu: Menu) {
menu.findItem(R.id.menu_home_mark_all_as_read).isVisible = hasUnreadRooms
super.onPrepareOptionsMenu(menu)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupCreateRoomButton()
@ -373,19 +351,6 @@ class RoomListFragment @Inject constructor(
override fun invalidate() = withState(roomListViewModel) { state ->
footerController.setData(state)
// Mark all as read menu
when (roomListParams.displayMode) {
RoomListDisplayMode.NOTIFICATIONS,
RoomListDisplayMode.PEOPLE,
RoomListDisplayMode.ROOMS -> {
val newValue = state.hasUnread
if (hasUnreadRooms != newValue) {
hasUnreadRooms = newValue
invalidateOptionsMenu()
}
}
else -> Unit
}
}
private fun checkEmptyState() {

View file

@ -160,7 +160,6 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
is RoomListAction.AcceptInvitation -> handleAcceptInvitation(action)
is RoomListAction.RejectInvitation -> handleRejectInvitation(action)
is RoomListAction.FilterWith -> handleFilter(action)
is RoomListAction.MarkAllRoomsRead -> handleMarkAllRoomsRead()
is RoomListAction.LeaveRoom -> handleLeaveRoom(action)
is RoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
is RoomListAction.ToggleTag -> handleToggleTag(action)
@ -276,15 +275,6 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
}
}
private fun handleMarkAllRoomsRead() = withState { _ ->
// state.asyncFilteredRooms.invoke()
// ?.flatMap { it.value }
// ?.filter { it.membership == Membership.JOIN }
// ?.map { it.roomId }
// ?.toList()
// ?.let { session.markAllAsRead(it, NoOpMatrixCallback()) }
}
private fun handleChangeNotificationMode(action: RoomListAction.ChangeRoomNotificationState) {
val room = session.getRoom(action.roomId)
if (room != null) {