mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Close Activity when room is left.
Create a dedicated ViewModel to handle that in Activity rather than multiple times in Fragments
This commit is contained in:
parent
530ce0952c
commit
4f5b1d9646
@ -32,6 +32,7 @@ import im.vector.riotx.features.crypto.verification.VerificationBottomSheet
|
||||
import im.vector.riotx.features.debug.DebugMenuActivity
|
||||
import im.vector.riotx.features.home.HomeActivity
|
||||
import im.vector.riotx.features.home.HomeModule
|
||||
import im.vector.riotx.features.home.room.detail.RoomDetailActivity
|
||||
import im.vector.riotx.features.home.room.detail.readreceipts.DisplayReadReceiptsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.action.MessageActionsBottomSheet
|
||||
import im.vector.riotx.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet
|
||||
@ -57,7 +58,9 @@ import im.vector.riotx.features.reactions.EmojiReactionPickerActivity
|
||||
import im.vector.riotx.features.reactions.widget.ReactionButton
|
||||
import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity
|
||||
import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActivity
|
||||
import im.vector.riotx.features.roommemberprofile.RoomMemberProfileActivity
|
||||
import im.vector.riotx.features.roommemberprofile.devices.DeviceListBottomSheet
|
||||
import im.vector.riotx.features.roomprofile.RoomProfileActivity
|
||||
import im.vector.riotx.features.settings.VectorSettingsActivity
|
||||
import im.vector.riotx.features.settings.devices.DeviceVerificationInfoBottomSheet
|
||||
import im.vector.riotx.features.share.IncomingShareActivity
|
||||
@ -101,6 +104,9 @@ interface ScreenComponent {
|
||||
* ========================================================================================== */
|
||||
|
||||
fun inject(activity: HomeActivity)
|
||||
fun inject(activity: RoomDetailActivity)
|
||||
fun inject(activity: RoomProfileActivity)
|
||||
fun inject(activity: RoomMemberProfileActivity)
|
||||
fun inject(activity: VectorSettingsActivity)
|
||||
fun inject(activity: KeysBackupManageActivity)
|
||||
fun inject(activity: EmojiReactionPickerActivity)
|
||||
|
@ -22,20 +22,43 @@ import android.os.Bundle
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.hideKeyboard
|
||||
import im.vector.riotx.core.extensions.replaceFragment
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.features.home.room.breadcrumbs.BreadcrumbsFragment
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipAction
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewModel
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewState
|
||||
import kotlinx.android.synthetic.main.activity_room_detail.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
class RoomDetailActivity :
|
||||
VectorBaseActivity(),
|
||||
ToolbarConfigurable,
|
||||
RequireActiveMembershipViewModel.Factory {
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_room_detail
|
||||
|
||||
private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel
|
||||
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
|
||||
|
||||
@Inject
|
||||
lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory
|
||||
|
||||
override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel {
|
||||
// Due to shortcut, we cannot use MvRx args. Pass the first roomId here
|
||||
return requireActiveMembershipViewModelFactory.create(initialState.copy(roomId = currentRoomId ?: ""))
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
// Simple filter
|
||||
private var currentRoomId: String? = null
|
||||
@ -68,6 +91,8 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
||||
requireActiveMembershipViewModel.observeViewEvents { finish() }
|
||||
|
||||
drawerLayout.addDrawerListener(drawerListener)
|
||||
}
|
||||
|
||||
@ -76,6 +101,7 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
// Do not replace the Fragment if it's the same roomId
|
||||
if (currentRoomId != switchToRoom.roomId) {
|
||||
currentRoomId = switchToRoom.roomId
|
||||
requireActiveMembershipViewModel.handle(RequireActiveMembershipAction.ChangeRoom(switchToRoom.roomId))
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, RoomDetailArgs(switchToRoom.roomId))
|
||||
}
|
||||
}
|
||||
@ -125,6 +151,7 @@ class RoomDetailActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcuts can't have intents with parcelables
|
||||
fun shortcutIntent(context: Context, roomId: String): Intent {
|
||||
return Intent(context, RoomDetailActivity::class.java).apply {
|
||||
action = ACTION_ROOM_DETAILS_FROM_SHORTCUT
|
||||
|
@ -753,15 +753,10 @@ class RoomDetailFragment @Inject constructor(
|
||||
|
||||
private fun renderRoomSummary(state: RoomDetailViewState) {
|
||||
state.asyncRoomSummary()?.let { roomSummary ->
|
||||
if (roomSummary.membership.isLeft()) {
|
||||
Timber.w("The room has been left")
|
||||
activity?.finish()
|
||||
} else {
|
||||
roomToolbarTitleView.text = roomSummary.displayName
|
||||
avatarRenderer.render(roomSummary.toMatrixItem(), roomToolbarAvatarImageView)
|
||||
roomToolbarTitleView.text = roomSummary.displayName
|
||||
avatarRenderer.render(roomSummary.toMatrixItem(), roomToolbarAvatarImageView)
|
||||
|
||||
renderSubTitle(state.typingMessage, roomSummary.topic)
|
||||
}
|
||||
renderSubTitle(state.typingMessage, roomSummary.topic)
|
||||
jumpToBottomView.count = roomSummary.notificationCount
|
||||
jumpToBottomView.drawBadge = roomSummary.hasUnreadMessages
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.room
|
||||
|
||||
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class RequireActiveMembershipAction : VectorViewModelAction {
|
||||
data class ChangeRoom(val roomId: String) : RequireActiveMembershipAction()
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.room
|
||||
|
||||
import im.vector.riotx.core.platform.VectorViewEvents
|
||||
|
||||
sealed class RequireActiveMembershipViewEvents : VectorViewEvents {
|
||||
object RoomLeft : RequireActiveMembershipViewEvents()
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.room
|
||||
|
||||
import com.airbnb.mvrx.ActivityViewModelContext
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.matrix.rx.unwrap
|
||||
import im.vector.riotx.core.extensions.exhaustive
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import io.reactivex.disposables.Disposable
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* This ViewModel observe a room summary and notify when the room is left
|
||||
*/
|
||||
class RequireActiveMembershipViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: RequireActiveMembershipViewState,
|
||||
private val session: Session)
|
||||
: VectorViewModel<RequireActiveMembershipViewState, RequireActiveMembershipAction, RequireActiveMembershipViewEvents>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<RequireActiveMembershipViewModel, RequireActiveMembershipViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: RequireActiveMembershipViewState): RequireActiveMembershipViewModel? {
|
||||
val factory = when (viewModelContext) {
|
||||
is FragmentViewModelContext -> viewModelContext.fragment as? Factory
|
||||
is ActivityViewModelContext -> viewModelContext.activity as? Factory
|
||||
}
|
||||
return factory?.create(state) ?: error("You should let your activity/fragment implements Factory interface")
|
||||
}
|
||||
}
|
||||
|
||||
private var currentDisposable: Disposable? = null
|
||||
|
||||
init {
|
||||
observeRoomSummary(initialState.roomId)
|
||||
}
|
||||
|
||||
private fun observeRoomSummary(roomId: String?) {
|
||||
currentDisposable?.dispose()
|
||||
|
||||
currentDisposable = roomId
|
||||
?.let { session.getRoom(it) }
|
||||
?.let { room ->
|
||||
room.rx().liveRoomSummary()
|
||||
.unwrap()
|
||||
.subscribe {
|
||||
if (it.membership.isLeft()) {
|
||||
Timber.w("The room has been left")
|
||||
_viewEvents.post(RequireActiveMembershipViewEvents.RoomLeft)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
currentDisposable?.dispose()
|
||||
}
|
||||
|
||||
override fun handle(action: RequireActiveMembershipAction) {
|
||||
when (action) {
|
||||
is RequireActiveMembershipAction.ChangeRoom -> {
|
||||
setState {
|
||||
copy(roomId = action.roomId)
|
||||
}
|
||||
observeRoomSummary(action.roomId)
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.room
|
||||
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import im.vector.riotx.features.roommemberprofile.RoomMemberProfileArgs
|
||||
import im.vector.riotx.features.roomprofile.RoomProfileArgs
|
||||
|
||||
data class RequireActiveMembershipViewState(
|
||||
val roomId: String? = null
|
||||
) : MvRxState {
|
||||
|
||||
// No constructor for RoomDetailArgs because of intent for Shortcut
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
|
||||
constructor(args: RoomMemberProfileArgs) : this(roomId = args.roomId)
|
||||
}
|
@ -20,32 +20,53 @@ package im.vector.riotx.features.roommemberprofile
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.addFragment
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewModel
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewState
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomMemberProfileActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
class RoomMemberProfileActivity :
|
||||
VectorBaseActivity(),
|
||||
ToolbarConfigurable,
|
||||
RequireActiveMembershipViewModel.Factory {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS"
|
||||
|
||||
fun newIntent(context: Context, args: RoomMemberProfileArgs): Intent {
|
||||
return Intent(context, RoomMemberProfileActivity::class.java).apply {
|
||||
putExtra(EXTRA_FRAGMENT_ARGS, args)
|
||||
putExtra(MvRx.KEY_ARG, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
|
||||
|
||||
@Inject
|
||||
lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory
|
||||
|
||||
override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel { // Due to shortcut, we cannot use MvRx args. Pass the roomId here
|
||||
return requireActiveMembershipViewModelFactory.create(initialState)
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_simple
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val fragmentArgs: RoomMemberProfileArgs = intent?.extras?.getParcelable(EXTRA_FRAGMENT_ARGS)
|
||||
?: return
|
||||
val fragmentArgs: RoomMemberProfileArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG) ?: return
|
||||
addFragment(R.id.simpleFragmentContainer, RoomMemberProfileFragment::class.java, fragmentArgs)
|
||||
}
|
||||
|
||||
requireActiveMembershipViewModel.observeViewEvents { finish() }
|
||||
}
|
||||
|
||||
override fun configure(toolbar: Toolbar) {
|
||||
|
@ -20,25 +20,32 @@ package im.vector.riotx.features.roomprofile
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.addFragment
|
||||
import im.vector.riotx.core.extensions.addFragmentToBackstack
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewModel
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewState
|
||||
import im.vector.riotx.features.roomprofile.members.RoomMemberListFragment
|
||||
import im.vector.riotx.features.roomprofile.settings.RoomSettingsFragment
|
||||
import im.vector.riotx.features.roomprofile.uploads.RoomUploadsFragment
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
class RoomProfileActivity :
|
||||
VectorBaseActivity(),
|
||||
ToolbarConfigurable,
|
||||
RequireActiveMembershipViewModel.Factory {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_ROOM_PROFILE_ARGS = "EXTRA_ROOM_PROFILE_ARGS"
|
||||
|
||||
fun newIntent(context: Context, roomId: String): Intent {
|
||||
val roomProfileArgs = RoomProfileArgs(roomId)
|
||||
return Intent(context, RoomProfileActivity::class.java).apply {
|
||||
putExtra(EXTRA_ROOM_PROFILE_ARGS, roomProfileArgs)
|
||||
putExtra(MvRx.KEY_ARG, roomProfileArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,11 +53,25 @@ class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
private lateinit var sharedActionViewModel: RoomProfileSharedActionViewModel
|
||||
private lateinit var roomProfileArgs: RoomProfileArgs
|
||||
|
||||
private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel()
|
||||
|
||||
@Inject
|
||||
lateinit var requireActiveMembershipViewModelFactory: RequireActiveMembershipViewModel.Factory
|
||||
|
||||
override fun create(initialState: RequireActiveMembershipViewState): RequireActiveMembershipViewModel {
|
||||
return requireActiveMembershipViewModelFactory.create(initialState)
|
||||
}
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
super.injectWith(injector)
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override fun getLayoutRes() = R.layout.activity_simple
|
||||
|
||||
override fun initUiAndData() {
|
||||
sharedActionViewModel = viewModelProvider.get(RoomProfileSharedActionViewModel::class.java)
|
||||
roomProfileArgs = intent?.extras?.getParcelable(EXTRA_ROOM_PROFILE_ARGS) ?: return
|
||||
roomProfileArgs = intent?.extras?.getParcelable(MvRx.KEY_ARG) ?: return
|
||||
if (isFirstCreation()) {
|
||||
addFragment(R.id.simpleFragmentContainer, RoomProfileFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
@ -64,6 +85,8 @@ class RoomProfileActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
}
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
||||
requireActiveMembershipViewModel.observeViewEvents { finish() }
|
||||
}
|
||||
|
||||
private fun openRoomUploads() {
|
||||
|
Loading…
Reference in New Issue
Block a user