Using navigator and new activity for the new screen

This commit is contained in:
Maxime NATUREL 2023-02-01 14:53:05 +01:00
parent 8aa89f1dfd
commit fb44562824
15 changed files with 100 additions and 79 deletions

View file

@ -327,6 +327,7 @@
<activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity" /> <activity android:name=".features.settings.devices.v2.details.SessionDetailsActivity" />
<activity android:name=".features.settings.devices.v2.rename.RenameSessionActivity" /> <activity android:name=".features.settings.devices.v2.rename.RenameSessionActivity" />
<activity android:name=".features.login.qr.QrCodeLoginActivity" /> <activity android:name=".features.login.qr.QrCodeLoginActivity" />
<activity android:name=".features.roomprofile.polls.detail.RoomPollDetailActivity" />
<!-- Services --> <!-- Services -->

View file

@ -37,7 +37,6 @@ import im.vector.app.features.roomprofile.members.RoomMemberListFragment
import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment import im.vector.app.features.roomprofile.notifications.RoomNotificationSettingsFragment
import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment import im.vector.app.features.roomprofile.permissions.RoomPermissionsFragment
import im.vector.app.features.roomprofile.polls.RoomPollsFragment import im.vector.app.features.roomprofile.polls.RoomPollsFragment
import im.vector.app.features.roomprofile.polls.detail.RoomPollDetailFragment
import im.vector.app.features.roomprofile.settings.RoomSettingsFragment import im.vector.app.features.roomprofile.settings.RoomSettingsFragment
import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment
import im.vector.lib.core.utils.compat.getParcelableCompat import im.vector.lib.core.utils.compat.getParcelableCompat
@ -106,7 +105,6 @@ class RoomProfileActivity :
RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads() RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers() RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings() RoomProfileSharedAction.OpenRoomNotificationSettings -> openRoomNotificationSettings()
is RoomProfileSharedAction.OpenPollDetails -> handleOpenPollDetails(sharedAction)
} }
} }
.launchIn(lifecycleScope) .launchIn(lifecycleScope)
@ -132,14 +130,6 @@ class RoomProfileActivity :
finish() finish()
} }
private fun handleOpenPollDetails(sharedAction: RoomProfileSharedAction.OpenPollDetails) {
addFragmentToBackstack(
views.simpleFragmentContainer,
RoomPollDetailFragment::class.java,
roomProfileArgs.copy(selectedPollId = sharedAction.pollId)
)
}
private fun openRoomPolls() { private fun openRoomPolls() {
addFragmentToBackstack(views.simpleFragmentContainer, RoomPollsFragment::class.java, roomProfileArgs) addFragmentToBackstack(views.simpleFragmentContainer, RoomPollsFragment::class.java, roomProfileArgs)
} }

View file

@ -26,7 +26,6 @@ sealed class RoomProfileSharedAction : VectorSharedAction {
object OpenRoomAliasesSettings : RoomProfileSharedAction() object OpenRoomAliasesSettings : RoomProfileSharedAction()
object OpenRoomPermissionsSettings : RoomProfileSharedAction() object OpenRoomPermissionsSettings : RoomProfileSharedAction()
object OpenRoomPolls : RoomProfileSharedAction() object OpenRoomPolls : RoomProfileSharedAction()
data class OpenPollDetails(val pollId: String) : RoomProfileSharedAction()
object OpenRoomUploads : RoomProfileSharedAction() object OpenRoomUploads : RoomProfileSharedAction()
object OpenRoomMembers : RoomProfileSharedAction() object OpenRoomMembers : RoomProfileSharedAction()
object OpenBannedRoomMembers : RoomProfileSharedAction() object OpenBannedRoomMembers : RoomProfileSharedAction()

View file

@ -20,6 +20,4 @@ import im.vector.app.core.platform.VectorViewModelAction
sealed interface RoomPollsAction : VectorViewModelAction { sealed interface RoomPollsAction : VectorViewModelAction {
object LoadMorePolls : RoomPollsAction object LoadMorePolls : RoomPollsAction
data class OnRoomPollsTypeChange(val roomPollsType: RoomPollsType) : RoomPollsAction
data class OnPollSelected(val selectedPollId: String) : RoomPollsAction
} }

View file

@ -20,9 +20,6 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.viewpager2.widget.ViewPager2
import com.airbnb.mvrx.args import com.airbnb.mvrx.args
import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.fragmentViewModel
import com.google.android.material.tabs.TabLayoutMediator import com.google.android.material.tabs.TabLayoutMediator
@ -69,35 +66,9 @@ class RoomPollsFragment : VectorBaseFragment<FragmentRoomPollsBinding>() {
tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position -> tabLayoutMediator = TabLayoutMediator(views.roomPollsTabs, views.roomPollsViewPager) { tab, position ->
when (position) { when (position) {
RoomPollsType.ACTIVE.ordinal -> { RoomPollsType.ACTIVE.ordinal -> tab.text = getString(R.string.room_polls_active)
tab.text = getString(R.string.room_polls_active) RoomPollsType.ENDED.ordinal -> tab.text = getString(R.string.room_polls_ended)
}
RoomPollsType.ENDED.ordinal -> {
tab.text = getString(R.string.room_polls_ended)
}
} }
}.also { it.attach() } }.also { it.attach() }
val onPageChangeCallback = object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
when (position) {
RoomPollsType.ACTIVE.ordinal -> {
viewModel.handle(RoomPollsAction.OnRoomPollsTypeChange(RoomPollsType.ACTIVE))
}
RoomPollsType.ENDED.ordinal -> {
viewModel.handle(RoomPollsAction.OnRoomPollsTypeChange(RoomPollsType.ENDED))
}
}
}
}
viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onCreate(owner: LifecycleOwner) {
views.roomPollsViewPager.registerOnPageChangeCallback(onPageChangeCallback)
}
override fun onDestroy(owner: LifecycleOwner) {
views.roomPollsViewPager.unregisterOnPageChangeCallback(onPageChangeCallback)
}
})
} }
} }

View file

@ -20,5 +20,4 @@ import im.vector.app.core.platform.VectorViewEvents
sealed class RoomPollsViewEvent : VectorViewEvents { sealed class RoomPollsViewEvent : VectorViewEvents {
object LoadingError : RoomPollsViewEvent() object LoadingError : RoomPollsViewEvent()
data class NavigateToPollDetail(val selectedPollId: String) : RoomPollsViewEvent()
} }

View file

@ -89,20 +89,9 @@ class RoomPollsViewModel @AssistedInject constructor(
override fun handle(action: RoomPollsAction) { override fun handle(action: RoomPollsAction) {
when (action) { when (action) {
RoomPollsAction.LoadMorePolls -> handleLoadMore() RoomPollsAction.LoadMorePolls -> handleLoadMore()
is RoomPollsAction.OnPollSelected -> handleOnPollSelected(action)
is RoomPollsAction.OnRoomPollsTypeChange -> handleOnRoomPollsTypeChange(action)
} }
} }
private fun handleOnRoomPollsTypeChange(action: RoomPollsAction.OnRoomPollsTypeChange) {
setState { copy(selectedRoomPollsType = action.roomPollsType) }
}
private fun handleOnPollSelected(action: RoomPollsAction.OnPollSelected) {
setState { copy(selectedPollId = action.selectedPollId) }
_viewEvents.post(RoomPollsViewEvent.NavigateToPollDetail(action.selectedPollId))
}
private fun handleLoadMore() = withState { viewState -> private fun handleLoadMore() = withState { viewState ->
viewModelScope.launch { viewModelScope.launch {
setState { copy(isLoadingMore = true) } setState { copy(isLoadingMore = true) }

View file

@ -27,14 +27,10 @@ data class RoomPollsViewState(
val canLoadMore: Boolean = true, val canLoadMore: Boolean = true,
val nbSyncedDays: Int = 0, val nbSyncedDays: Int = 0,
val isSyncing: Boolean = false, val isSyncing: Boolean = false,
val selectedPollId: String? = null,
val selectedRoomPollsType: RoomPollsType = RoomPollsType.ACTIVE,
) : MavericksState { ) : MavericksState {
constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId) constructor(roomProfileArgs: RoomProfileArgs) : this(roomId = roomProfileArgs.roomId)
fun hasNoPolls() = polls.isEmpty() fun hasNoPolls() = polls.isEmpty()
fun hasNoPollsAndCanLoadMore() = !isSyncing && hasNoPolls() && canLoadMore fun hasNoPollsAndCanLoadMore() = !isSyncing && hasNoPolls() && canLoadMore
fun getSelectedPoll() = polls.find { it.id == selectedPollId }
fun canVoteSelectedPoll() = selectedRoomPollsType == RoomPollsType.ACTIVE
} }

View file

@ -0,0 +1,56 @@
/*
* Copyright 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.roomprofile.polls.detail
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.airbnb.mvrx.Mavericks
import dagger.hilt.android.AndroidEntryPoint
import im.vector.app.core.extensions.addFragment
import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivitySimpleBinding
import im.vector.lib.core.utils.compat.getParcelableExtraCompat
/**
* Display the details of a given poll.
*/
@AndroidEntryPoint
class RoomPollDetailActivity : VectorBaseActivity<ActivitySimpleBinding>() {
override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isFirstCreation()) {
addFragment(
container = views.simpleFragmentContainer,
fragmentClass = RoomPollDetailFragment::class.java,
params = intent.getParcelableExtraCompat(Mavericks.KEY_ARG)
)
}
}
companion object {
fun newIntent(context: Context, pollId: String): Intent {
return Intent(context, RoomPollDetailActivity::class.java).apply {
putExtra(Mavericks.KEY_ARG, RoomPollDetailArgs(pollId))
}
}
}
}

View file

@ -22,9 +22,8 @@ import im.vector.app.features.roomprofile.polls.RoomPollsViewState
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
import javax.inject.Inject import javax.inject.Inject
class RoomPollDetailController @Inject constructor( class RoomPollDetailController @Inject constructor()
: TypedEpoxyController<RoomPollDetailViewState>() {
) : TypedEpoxyController<RoomPollDetailViewState>() {
override fun buildModels(viewState: RoomPollDetailViewState?) { override fun buildModels(viewState: RoomPollDetailViewState?) {
viewState ?: return viewState ?: return

View file

@ -36,7 +36,6 @@ import javax.inject.Inject
@Parcelize @Parcelize
data class RoomPollDetailArgs( data class RoomPollDetailArgs(
val roomId: String,
val pollId: String, val pollId: String,
) : Parcelable ) : Parcelable

View file

@ -25,10 +25,11 @@ class RoomPollDetailViewModel @AssistedInject constructor(
) : VectorViewModel<RoomPollDetailViewState, RoomPollDetailAction, RoomPollDetailViewEvent>(initialState) { ) : VectorViewModel<RoomPollDetailViewState, RoomPollDetailAction, RoomPollDetailViewEvent>(initialState) {
init { init {
// Subscribe to the poll event and map it // TODO observe poll using TimelineService.getTimelineEventLive
// TODO create a dedicated useCase and mapper
} }
override fun handle(action: RoomPollDetailAction) { override fun handle(action: RoomPollDetailAction) {
// TODO handle go to timeline action
} }
} }

View file

@ -19,11 +19,9 @@ package im.vector.app.features.roomprofile.polls.detail
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
data class RoomPollDetailViewState( data class RoomPollDetailViewState(
val roomId: String, val pollId: String,
val pollId: String, val pollDetail: RoomPollDetail? = null,
val pollDetail: RoomPollDetail? = null,
) : MavericksState { ) : MavericksState {
constructor(roomPollDetailArgs: RoomPollDetailArgs) constructor(roomPollDetailArgs: RoomPollDetailArgs) : this(pollId = roomPollDetailArgs.pollId)
: this(roomId = roomPollDetailArgs.roomId, pollId = roomPollDetailArgs.pollId)
} }

View file

@ -29,8 +29,6 @@ import im.vector.app.core.extensions.configureWith
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.core.resources.StringProvider import im.vector.app.core.resources.StringProvider
import im.vector.app.databinding.FragmentRoomPollsListBinding import im.vector.app.databinding.FragmentRoomPollsListBinding
import im.vector.app.features.roomprofile.RoomProfileSharedAction
import im.vector.app.features.roomprofile.RoomProfileSharedActionViewModel
import im.vector.app.features.roomprofile.polls.RoomPollsAction import im.vector.app.features.roomprofile.polls.RoomPollsAction
import im.vector.app.features.roomprofile.polls.RoomPollsLoadingError import im.vector.app.features.roomprofile.polls.RoomPollsLoadingError
import im.vector.app.features.roomprofile.polls.RoomPollsType import im.vector.app.features.roomprofile.polls.RoomPollsType
@ -49,8 +47,10 @@ abstract class RoomPollsListFragment :
@Inject @Inject
lateinit var stringProvider: StringProvider lateinit var stringProvider: StringProvider
@Inject
lateinit var viewNavigator: RoomPollsListNavigator
private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class) private val viewModel: RoomPollsViewModel by parentFragmentViewModel(RoomPollsViewModel::class)
private lateinit var sharedActionViewModel: RoomProfileSharedActionViewModel
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentRoomPollsListBinding {
return FragmentRoomPollsListBinding.inflate(inflater, container, false) return FragmentRoomPollsListBinding.inflate(inflater, container, false)
@ -58,7 +58,6 @@ abstract class RoomPollsListFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
sharedActionViewModel = activityViewModelProvider[RoomProfileSharedActionViewModel::class.java]
observeViewEvents() observeViewEvents()
setupList() setupList()
setupLoadMoreButton() setupLoadMoreButton()
@ -68,9 +67,6 @@ abstract class RoomPollsListFragment :
viewModel.observeViewEvents { viewEvent -> viewModel.observeViewEvents { viewEvent ->
when (viewEvent) { when (viewEvent) {
RoomPollsViewEvent.LoadingError -> showErrorInSnackbar(RoomPollsLoadingError()) RoomPollsViewEvent.LoadingError -> showErrorInSnackbar(RoomPollsLoadingError())
is RoomPollsViewEvent.NavigateToPollDetail -> {
sharedActionViewModel.post(RoomProfileSharedAction.OpenPollDetails(viewEvent.selectedPollId))
}
} }
} }
} }
@ -132,7 +128,7 @@ abstract class RoomPollsListFragment :
} }
override fun onPollClicked(pollId: String) { override fun onPollClicked(pollId: String) {
viewModel.handle(RoomPollsAction.OnPollSelected(pollId)) viewNavigator.goToPollDetails(requireContext(), pollId)
} }
override fun onLoadMoreClicked() { override fun onLoadMoreClicked() {

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 2023 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.roomprofile.polls.list.ui
import android.content.Context
import im.vector.app.features.roomprofile.polls.detail.RoomPollDetailActivity
import javax.inject.Inject
// TODO add unit tests
class RoomPollsListNavigator @Inject constructor() {
fun goToPollDetails(context: Context, pollId: String) {
context.startActivity(RoomPollDetailActivity.newIntent(context, pollId))
}
}