Introduce Navigator

This commit is contained in:
Benoit Marty 2019-05-28 21:12:09 +02:00
parent 6244913ab9
commit e70a483d6b
12 changed files with 122 additions and 28 deletions

View File

@ -18,6 +18,7 @@ package im.vector.riotredesign.core.di


import android.content.Context import android.content.Context
import android.content.Context.MODE_PRIVATE import android.content.Context.MODE_PRIVATE
import androidx.fragment.app.Fragment
import im.vector.matrix.android.api.Matrix import im.vector.matrix.android.api.Matrix
import im.vector.riotredesign.core.error.ErrorFormatter import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.resources.LocaleProvider import im.vector.riotredesign.core.resources.LocaleProvider
@ -27,6 +28,8 @@ import im.vector.riotredesign.features.home.HomeRoomListObservableStore
import im.vector.riotredesign.features.home.group.SelectedGroupStore import im.vector.riotredesign.features.home.group.SelectedGroupStore
import im.vector.riotredesign.features.home.room.list.AlphabeticalRoomComparator import im.vector.riotredesign.features.home.room.list.AlphabeticalRoomComparator
import im.vector.riotredesign.features.home.room.list.ChronologicalRoomComparator import im.vector.riotredesign.features.home.room.list.ChronologicalRoomComparator
import im.vector.riotredesign.features.navigation.DefaultNavigator
import im.vector.riotredesign.features.navigation.Navigator
import im.vector.riotredesign.features.notifications.NotificationDrawerManager import im.vector.riotredesign.features.notifications.NotificationDrawerManager
import org.koin.dsl.module.module import org.koin.dsl.module.module


@ -78,5 +81,9 @@ class AppModule(private val context: Context) {
Matrix.getInstance().currentSession!! Matrix.getInstance().currentSession!!
} }


factory { (fragment: Fragment) ->
DefaultNavigator(fragment) as Navigator
}

} }
} }

View File

@ -294,7 +294,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity() {
* ========================================================================================== */ * ========================================================================================== */


fun notImplemented(message: String = "") { fun notImplemented(message: String = "") {
toast(getString(R.string.not_implemented) + message.takeIf { message.isNotBlank() }.run { ": $message" }) toast(getString(R.string.not_implemented) + message.takeIf { message.isNotBlank() }?.let { ": $it" })
} }


} }

View File

@ -28,9 +28,11 @@ import butterknife.Unbinder
import com.airbnb.mvrx.BaseMvRxFragment import com.airbnb.mvrx.BaseMvRxFragment
import com.airbnb.mvrx.MvRx import com.airbnb.mvrx.MvRx
import com.bumptech.glide.util.Util.assertMainThread import com.bumptech.glide.util.Util.assertMainThread
import com.google.android.material.snackbar.Snackbar import im.vector.riotredesign.features.navigation.Navigator
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import org.koin.android.ext.android.inject
import org.koin.core.parameter.parametersOf
import timber.log.Timber import timber.log.Timber


abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed { abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
@ -42,6 +44,12 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), OnBackPressed {
activity as VectorBaseActivity activity as VectorBaseActivity
} }


/* ==========================================================================================
* Navigator
* ========================================================================================== */

protected val navigator: Navigator by inject { parametersOf(this) }

/* ========================================================================================== /* ==========================================================================================
* Life cycle * Life cycle
* ========================================================================================== */ * ========================================================================================== */

View File

@ -52,7 +52,7 @@ class HomeDrawerFragment : VectorBaseFragment() {
} }
} }
homeDrawerHeaderSettingsView.setOnClickListener { homeDrawerHeaderSettingsView.setOnClickListener {
startActivity(VectorSettingsActivity.getIntent(requireContext(), "TODO")) navigator.openSettings()
} }
} }
} }

View File

@ -53,7 +53,7 @@ class HomeModule {
} }


scope(HOME_SCOPE) { scope(HOME_SCOPE) {
HomePermalinkHandler(get()) HomePermalinkHandler(get(), get())
} }


// Fragment scopes // Fragment scopes

View File

@ -21,8 +21,7 @@ import androidx.fragment.app.FragmentManager
import im.vector.matrix.android.api.session.group.model.GroupSummary import im.vector.matrix.android.api.session.group.model.GroupSummary
import im.vector.riotredesign.R import im.vector.riotredesign.R
import im.vector.riotredesign.core.extensions.replaceFragment import im.vector.riotredesign.core.extensions.replaceFragment
import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity import im.vector.riotredesign.features.navigation.Navigator
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
import kotlinx.android.synthetic.main.activity_home.* import kotlinx.android.synthetic.main.activity_home.*
import timber.log.Timber import timber.log.Timber


@ -43,14 +42,13 @@ class HomeNavigator {
} }


fun openRoomDetail(roomId: String, fun openRoomDetail(roomId: String,
eventId: String?) { eventId: String?,
navigator: Navigator) {
Timber.v("Open room detail $roomId - $eventId") Timber.v("Open room detail $roomId - $eventId")
activity?.let { activity?.let {
//TODO enable eventId permalink. It doesn't work enough at the moment. //TODO enable eventId permalink. It doesn't work enough at the moment.
it.drawerLayout?.closeDrawer(GravityCompat.START) it.drawerLayout?.closeDrawer(GravityCompat.START)
val args = RoomDetailArgs(roomId) navigator.openRoom(roomId)
val roomDetailIntent = RoomDetailActivity.newIntent(it, args)
it.startActivity(roomDetailIntent)
} }
} }



View File

@ -19,8 +19,10 @@ 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.navigation.Navigator


class HomePermalinkHandler(private val navigator: HomeNavigator) { class HomePermalinkHandler(private val homeNavigator: HomeNavigator,
private val navigator: Navigator) {


fun launch(deepLink: String?) { fun launch(deepLink: String?) {
val uri = deepLink?.let { Uri.parse(it) } val uri = deepLink?.let { Uri.parse(it) }
@ -34,16 +36,16 @@ class HomePermalinkHandler(private val navigator: HomeNavigator) {
val permalinkData = PermalinkParser.parse(deepLink) val permalinkData = PermalinkParser.parse(deepLink)
when (permalinkData) { when (permalinkData) {
is PermalinkData.EventLink -> { is PermalinkData.EventLink -> {
navigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId) homeNavigator.openRoomDetail(permalinkData.roomIdOrAlias, permalinkData.eventId, navigator)
} }
is PermalinkData.RoomLink -> { is PermalinkData.RoomLink -> {
navigator.openRoomDetail(permalinkData.roomIdOrAlias, null) homeNavigator.openRoomDetail(permalinkData.roomIdOrAlias, null, navigator)
} }
is PermalinkData.GroupLink -> { is PermalinkData.GroupLink -> {
navigator.openGroupDetail(permalinkData.groupId) homeNavigator.openGroupDetail(permalinkData.groupId)
} }
is PermalinkData.UserLink -> { is PermalinkData.UserLink -> {
navigator.openUserDetail(permalinkData.userId) homeNavigator.openUserDetail(permalinkData.userId)
} }
is PermalinkData.FallbackLink -> { is PermalinkData.FallbackLink -> {



View File

@ -29,7 +29,6 @@ import im.vector.riotredesign.core.epoxy.LayoutManagerStateRestorer
import im.vector.riotredesign.core.extensions.observeEvent import im.vector.riotredesign.core.extensions.observeEvent
import im.vector.riotredesign.core.platform.StateView import im.vector.riotredesign.core.platform.StateView
import im.vector.riotredesign.core.platform.VectorBaseFragment import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.HomeNavigator
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import kotlinx.android.synthetic.main.fragment_room_list.* import kotlinx.android.synthetic.main.fragment_room_list.*
@ -59,7 +58,6 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {


private val roomListParams: RoomListParams by args() private val roomListParams: RoomListParams by args()
private val roomController by inject<RoomSummaryController>() private val roomController by inject<RoomSummaryController>()
private val homeNavigator by inject<HomeNavigator>()
private val roomListViewModel: RoomListViewModel by fragmentViewModel() private val roomListViewModel: RoomListViewModel by fragmentViewModel()


override fun getLayoutResId() = R.layout.fragment_room_list override fun getLayoutResId() = R.layout.fragment_room_list
@ -70,15 +68,14 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Callback {
setupCreateRoomButton() setupCreateRoomButton()
roomListViewModel.subscribe { renderState(it) } roomListViewModel.subscribe { renderState(it) }
roomListViewModel.openRoomLiveData.observeEvent(this) { roomListViewModel.openRoomLiveData.observeEvent(this) {
homeNavigator.openRoomDetail(it, null) navigator.openRoom(it)
} }
} }


private fun setupCreateRoomButton() { private fun setupCreateRoomButton() {
createRoomButton.setImageResource(R.drawable.ic_add_white) createRoomButton.setImageResource(R.drawable.ic_add_white)
createRoomButton.setOnClickListener { createRoomButton.setOnClickListener {
// Start Activity for now navigator.openRoomDirectory()
startActivity(Intent(requireActivity(), RoomDirectoryActivity::class.java))
} }
} }



View File

@ -0,0 +1,53 @@
/*
* 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.riotredesign.features.navigation

import android.app.Activity
import android.content.Intent
import androidx.fragment.app.Fragment
import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom
import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryActivity
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity
import im.vector.riotredesign.features.settings.VectorSettingsActivity

class DefaultNavigator(private val fraqment: Fragment) : Navigator {

val activity: Activity = fraqment.requireActivity()

override fun openRoom(roomId: String) {
val args = RoomDetailArgs(roomId)
val intent = RoomDetailActivity.newIntent(activity, args)
activity.startActivity(intent)
}

override fun openRoomPreview(publicRoom: PublicRoom) {
val intent = RoomPreviewActivity.getIntent(activity, publicRoom)
activity.startActivity(intent)
}

override fun openRoomDirectory() {
val intent = Intent(activity, RoomDirectoryActivity::class.java)
activity.startActivity(intent)
}

override fun openSettings() {
val intent = VectorSettingsActivity.getIntent(activity, "TODO")
activity.startActivity(intent)
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.riotredesign.features.navigation

import im.vector.matrix.android.api.session.room.model.roomdirectory.PublicRoom

interface Navigator {

fun openRoom(roomId: String)

fun openRoomPreview(publicRoom: PublicRoom)

fun openRoomDirectory()

fun openSettings()

}

View File

@ -30,8 +30,6 @@ import im.vector.riotredesign.R
import im.vector.riotredesign.core.error.ErrorFormatter import im.vector.riotredesign.core.error.ErrorFormatter
import im.vector.riotredesign.core.extensions.addFragmentToBackstack import im.vector.riotredesign.core.extensions.addFragmentToBackstack
import im.vector.riotredesign.core.platform.VectorBaseFragment import im.vector.riotredesign.core.platform.VectorBaseFragment
import im.vector.riotredesign.features.home.room.detail.RoomDetailActivity
import im.vector.riotredesign.features.home.room.detail.RoomDetailArgs
import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerFragment import im.vector.riotredesign.features.roomdirectory.picker.RoomDirectoryPickerFragment
import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity import im.vector.riotredesign.features.roomdirectory.roompreview.RoomPreviewActivity
import io.reactivex.rxkotlin.subscribeBy import io.reactivex.rxkotlin.subscribeBy
@ -122,14 +120,12 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback


when (joinState) { when (joinState) {
JoinState.JOINED -> { JoinState.JOINED -> {
val args = RoomDetailArgs(publicRoom.roomId) navigator.openRoom(publicRoom.roomId)
val roomDetailIntent = RoomDetailActivity.newIntent(requireActivity(), args)
requireActivity().startActivity(roomDetailIntent)
} }
JoinState.NOT_JOINED, JoinState.NOT_JOINED,
JoinState.JOINING_ERROR -> { JoinState.JOINING_ERROR -> {
// ROOM PREVIEW // ROOM PREVIEW
requireActivity().startActivity(RoomPreviewActivity.getIntent(requireActivity(), publicRoom)) navigator.openRoomPreview(publicRoom)
} }
else -> { else -> {
Snackbar.make(publicRoomsCoordinator, getString(R.string.please_wait), Snackbar.LENGTH_SHORT) Snackbar.make(publicRoomsCoordinator, getString(R.string.please_wait), Snackbar.LENGTH_SHORT)

View File

@ -93,8 +93,10 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
roomPreviewNoPreviewError.setTextOrHide(errorFormatter.toHumanReadable(state.lastError)) roomPreviewNoPreviewError.setTextOrHide(errorFormatter.toHumanReadable(state.lastError))


if (state.roomJoinState == JoinState.JOINED) { if (state.roomJoinState == JoinState.JOINED) {
// TODO Quit this screen and open the room // Quit this screen
vectorBaseActivity.notImplemented("Open newly join room") requireActivity().finish()
// Open room
navigator.openRoom(roomPreviewData.roomId)
} }
} }
} }