Iterate on navigation... We have to think about backstack, maybe using a finite state machine. WIP

This commit is contained in:
ganfra 2018-12-27 19:32:52 +01:00
parent 337fd075dd
commit c42be8141e
9 changed files with 60 additions and 24 deletions

View File

@ -0,0 +1,4 @@
package im.vector.riotredesign.features
class RootFlowCoordinator {
}

View File

@ -0,0 +1,4 @@
package im.vector.riotredesign.features.home
class HomeFlowCoordinator {
}

View File

@ -1,11 +1,10 @@
package im.vector.riotredesign.core package im.vector.riotredesign.features.home
import android.net.Uri import android.net.Uri
import im.vector.matrix.android.api.permalinks.PermalinkData import im.vector.matrix.android.api.permalinks.PermalinkData
import im.vector.matrix.android.api.permalinks.PermalinkParser import im.vector.matrix.android.api.permalinks.PermalinkParser
import im.vector.riotredesign.features.home.HomeNavigator
class HomePermalinkNavigator(private val navigator: HomeNavigator) { class HomePermalinkHandler(private val navigator: HomeNavigator) {
fun launch(deepLink: String?) { fun launch(deepLink: String?) {
val uri = deepLink?.let { Uri.parse(it) } val uri = deepLink?.let { Uri.parse(it) }
@ -22,7 +21,7 @@ class HomePermalinkNavigator(private val navigator: HomeNavigator) {
navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId) navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId)
} }
is PermalinkData.RoomLink -> { is PermalinkData.RoomLink -> {
navigator.openRoomDetail(permalinkData.roomIdOrAlias, null ) navigator.openRoomDetail(permalinkData.roomIdOrAlias, null)
} }
is PermalinkData.GroupLink -> { is PermalinkData.GroupLink -> {
navigator.openGroupDetail(permalinkData.groupId) navigator.openGroupDetail(permalinkData.groupId)

View File

@ -4,6 +4,7 @@ import android.support.v4.app.FragmentActivity
import com.airbnb.mvrx.BaseMvRxViewModel import com.airbnb.mvrx.BaseMvRxViewModel
import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.MvRxViewModelFactory
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.permalinks.PermalinkData
import im.vector.matrix.android.api.session.Session import im.vector.matrix.android.api.session.Session
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
@ -25,19 +26,42 @@ class HomeViewModel(initialState: HomeViewState, private val session: Session) :
fun accept(action: HomeActions) { fun accept(action: HomeActions) {
when (action) { when (action) {
is HomeActions.SelectRoom -> handleSelectRoom(action) is HomeActions.SelectRoom -> handleSelectRoom(action)
is HomeActions.SelectGroup -> handleSelectGroup(action) is HomeActions.SelectGroup -> handleSelectGroup(action)
is HomeActions.RoomDisplayed -> setState { copy(shouldOpenRoomDetail = false) } is HomeActions.RoomDisplayed -> setState { copy(shouldOpenRoomDetail = false) }
is HomeActions.PermalinkClicked -> handlePermalinkClicked(action)
} }
} }
// PRIVATE METHODS ***************************************************************************** // PRIVATE METHODS *****************************************************************************
private fun handlePermalinkClicked(action: HomeActions.PermalinkClicked) {
withState { state ->
when (action.permalinkData) {
is PermalinkData.EventLink -> {
}
is PermalinkData.RoomLink -> {
}
is PermalinkData.GroupLink -> {
}
is PermalinkData.UserLink -> {
}
is PermalinkData.FallbackLink -> {
}
}
}
}
private fun handleSelectRoom(action: HomeActions.SelectRoom) { private fun handleSelectRoom(action: HomeActions.SelectRoom) {
withState { state -> withState { state ->
if (state.selectedRoom?.roomId != action.roomSummary.roomId) { if (state.selectedRoomId != action.roomSummary.roomId) {
session.saveLastSelectedRoom(action.roomSummary) session.saveLastSelectedRoom(action.roomSummary)
setState { copy(selectedRoom = action.roomSummary, shouldOpenRoomDetail = true) } setState { copy(selectedRoomId = action.roomSummary.roomId, shouldOpenRoomDetail = true) }
} }
} }
} }
@ -56,21 +80,20 @@ class HomeViewModel(initialState: HomeViewState, private val session: Session) :
session session
.rx().liveRoomSummaries() .rx().liveRoomSummaries()
.execute { async -> .execute { async ->
val summaries = async() val summaries = async()
val directRooms = summaries?.filter { it.isDirect } ?: emptyList() val directRooms = summaries?.filter { it.isDirect } ?: emptyList()
val groupRooms = summaries?.filter { !it.isDirect } ?: emptyList() val groupRooms = summaries?.filter { !it.isDirect } ?: emptyList()
val selectedRoom = selectedRoom val selectedRoomId = selectedRoomId
?: session.lastSelectedRoom() ?: session.lastSelectedRoom()?.roomId
?: directRooms.firstOrNull() ?: directRooms.firstOrNull()?.roomId
?: groupRooms.firstOrNull() ?: groupRooms.firstOrNull()?.roomId
copy( copy(
asyncRooms = async, asyncRooms = async,
directRooms = directRooms, directRooms = directRooms,
groupRooms = groupRooms, groupRooms = groupRooms,
selectedRoom = selectedRoom selectedRoomId = selectedRoomId
) )
} }
} }

View File

@ -10,7 +10,8 @@ data class HomeViewState(
val asyncRooms: Async<List<RoomSummary>> = Uninitialized, val asyncRooms: Async<List<RoomSummary>> = Uninitialized,
val directRooms: List<RoomSummary> = emptyList(), val directRooms: List<RoomSummary> = emptyList(),
val groupRooms: List<RoomSummary> = emptyList(), val groupRooms: List<RoomSummary> = emptyList(),
val selectedRoom: RoomSummary? = null, val selectedRoomId: String? = null,
val selectedEventId: String? = null,
val shouldOpenRoomDetail: Boolean = true, val shouldOpenRoomDetail: Boolean = true,
val asyncGroups: Async<List<GroupSummary>> = Uninitialized, val asyncGroups: Async<List<GroupSummary>> = Uninitialized,
val selectedGroup: GroupSummary? = null val selectedGroup: GroupSummary? = null

View File

@ -7,6 +7,7 @@ import android.support.v7.widget.LinearLayoutManager
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 com.airbnb.mvrx.activityViewModel
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.permalinks.PermalinkParser import im.vector.matrix.android.api.permalinks.PermalinkParser
@ -20,11 +21,12 @@ import im.vector.riotredesign.core.platform.ToolbarConfigurable
import im.vector.riotredesign.core.utils.FragmentArgumentDelegate import im.vector.riotredesign.core.utils.FragmentArgumentDelegate
import im.vector.riotredesign.core.utils.UnsafeFragmentArgumentDelegate import im.vector.riotredesign.core.utils.UnsafeFragmentArgumentDelegate
import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.HomeActions
import im.vector.riotredesign.features.home.HomeViewModel
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
import kotlinx.android.synthetic.main.fragment_room_detail.* import kotlinx.android.synthetic.main.fragment_room_detail.*
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koin.core.parameter.parametersOf import org.koin.core.parameter.parametersOf
import timber.log.Timber
class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback { class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
@ -38,6 +40,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
} }
} }
private val viewModel: HomeViewModel by activityViewModel()
private val currentSession = Matrix.getInstance().currentSession private val currentSession = Matrix.getInstance().currentSession
private var roomId: String by UnsafeFragmentArgumentDelegate() private var roomId: String by UnsafeFragmentArgumentDelegate()
private var eventId: String? by FragmentArgumentDelegate() private var eventId: String? by FragmentArgumentDelegate()
@ -106,7 +109,7 @@ class RoomDetailFragment : RiotFragment(), TimelineEventController.Callback {
override fun onUrlClicked(url: String) { override fun onUrlClicked(url: String) {
val permalinkData = PermalinkParser.parse(url) val permalinkData = PermalinkParser.parse(url)
Timber.v("Permalink data : $permalinkData") viewModel.accept(HomeActions.PermalinkClicked(permalinkData))
} }
} }

View File

@ -50,8 +50,8 @@ class RoomListFragment : RiotFragment(), RoomSummaryController.Callback {
is Success -> renderSuccess(state) is Success -> renderSuccess(state)
is Fail -> renderFailure(state.asyncRooms.error) is Fail -> renderFailure(state.asyncRooms.error)
} }
if (state.shouldOpenRoomDetail && state.selectedRoom != null) { if (state.shouldOpenRoomDetail && state.selectedRoomId != null) {
homeNavigator.openRoomDetail(state.selectedRoom.roomId, null) homeNavigator.openRoomDetail(state.selectedRoomId, null)
viewModel.accept(HomeActions.RoomDisplayed) viewModel.accept(HomeActions.RoomDisplayed)
} }
} }

View File

@ -34,7 +34,7 @@ class RoomSummaryController(private val callback: Callback? = null
.isNotEmpty() .isNotEmpty()
} }
} }
buildRoomModels(filteredDirectRooms, viewState.selectedRoom) buildRoomModels(filteredDirectRooms, viewState.selectedRoomId)
} }
RoomCategoryItem( RoomCategoryItem(
@ -52,14 +52,14 @@ class RoomSummaryController(private val callback: Callback? = null
val filteredGroupRooms = viewState.groupRooms.filter { val filteredGroupRooms = viewState.groupRooms.filter {
viewState.selectedGroup?.roomIds?.contains(it.roomId) ?: true viewState.selectedGroup?.roomIds?.contains(it.roomId) ?: true
} }
buildRoomModels(filteredGroupRooms, viewState.selectedRoom) buildRoomModels(filteredGroupRooms, viewState.selectedRoomId)
} }
} }
private fun buildRoomModels(summaries: List<RoomSummary>, selected: RoomSummary?) { private fun buildRoomModels(summaries: List<RoomSummary>, selectedRoomId: String?) {
summaries.forEach { roomSummary -> summaries.forEach { roomSummary ->
val isSelected = roomSummary.roomId == selected?.roomId val isSelected = roomSummary.roomId == selectedRoomId
RoomSummaryItem( RoomSummaryItem(
roomName = roomSummary.displayName, roomName = roomSummary.displayName,
avatarUrl = roomSummary.avatarUrl, avatarUrl = roomSummary.avatarUrl,

View File

@ -0,0 +1,2 @@
package im.vector.riotredesign.features.login