Code review
This commit is contained in:
parent
ecceb0fb03
commit
168633b466
@ -81,7 +81,7 @@ import im.vector.app.features.spaces.InviteRoomSpaceChooserBottomSheet
|
|||||||
import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
||||||
import im.vector.app.features.spaces.SpaceCreationActivity
|
import im.vector.app.features.spaces.SpaceCreationActivity
|
||||||
import im.vector.app.features.spaces.SpaceExploreActivity
|
import im.vector.app.features.spaces.SpaceExploreActivity
|
||||||
import im.vector.app.features.spaces.SpaceInviteBottomSheet
|
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
|
||||||
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
||||||
import im.vector.app.features.spaces.manage.SpaceManageActivity
|
import im.vector.app.features.spaces.manage.SpaceManageActivity
|
||||||
import im.vector.app.features.terms.ReviewTermsActivity
|
import im.vector.app.features.terms.ReviewTermsActivity
|
||||||
|
@ -60,9 +60,9 @@ import im.vector.app.features.settings.VectorPreferences
|
|||||||
import im.vector.app.features.settings.VectorSettingsActivity
|
import im.vector.app.features.settings.VectorSettingsActivity
|
||||||
import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
||||||
import im.vector.app.features.spaces.SpaceCreationActivity
|
import im.vector.app.features.spaces.SpaceCreationActivity
|
||||||
import im.vector.app.features.spaces.SpaceInviteBottomSheet
|
|
||||||
import im.vector.app.features.spaces.SpacePreviewActivity
|
import im.vector.app.features.spaces.SpacePreviewActivity
|
||||||
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
||||||
|
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
import im.vector.app.features.workers.signout.ServerBackupStatusViewModel
|
||||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
|
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
|
||||||
@ -89,7 +89,8 @@ class HomeActivity :
|
|||||||
UnknownDeviceDetectorSharedViewModel.Factory,
|
UnknownDeviceDetectorSharedViewModel.Factory,
|
||||||
ServerBackupStatusViewModel.Factory,
|
ServerBackupStatusViewModel.Factory,
|
||||||
UnreadMessagesSharedViewModel.Factory,
|
UnreadMessagesSharedViewModel.Factory,
|
||||||
NavigationInterceptor {
|
NavigationInterceptor,
|
||||||
|
SpaceInviteBottomSheet.InteractionListener {
|
||||||
|
|
||||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||||
|
|
||||||
@ -212,15 +213,7 @@ class HomeActivity :
|
|||||||
.show(supportFragmentManager, "SPACE_SETTINGS")
|
.show(supportFragmentManager, "SPACE_SETTINGS")
|
||||||
}
|
}
|
||||||
is HomeActivitySharedAction.OpenSpaceInvite -> {
|
is HomeActivitySharedAction.OpenSpaceInvite -> {
|
||||||
SpaceInviteBottomSheet.newInstance(sharedAction.spaceId, object : SpaceInviteBottomSheet.InteractionListener {
|
SpaceInviteBottomSheet.newInstance(sharedAction.spaceId)
|
||||||
override fun onAccept(spaceId: String) {
|
|
||||||
navigator.switchToSpace(this@HomeActivity, spaceId, Navigator.PostSwitchSpaceAction.None)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDecline(spaceId: String) {
|
|
||||||
// nop
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.show(supportFragmentManager, "SPACE_INVITE")
|
.show(supportFragmentManager, "SPACE_INVITE")
|
||||||
}
|
}
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
@ -527,6 +520,14 @@ class HomeActivity :
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun spaceInviteBottomSheetOnAccept(spaceId: String) {
|
||||||
|
navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun spaceInviteBottomSheetOnDecline(spaceId: String) {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newIntent(context: Context, clearNotification: Boolean = false, accountCreation: Boolean = false): Intent {
|
fun newIntent(context: Context, clearNotification: Boolean = false, accountCreation: Boolean = false): Intent {
|
||||||
val args = HomeActivityArgs(
|
val args = HomeActivityArgs(
|
||||||
|
@ -14,8 +14,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package im.vector.app.features.spaces
|
package im.vector.app.features.spaces.invite
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
@ -23,30 +24,30 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
import com.airbnb.mvrx.args
|
import com.airbnb.mvrx.args
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.app.R
|
import im.vector.app.R
|
||||||
import im.vector.app.core.di.ActiveSessionHolder
|
|
||||||
import im.vector.app.core.di.ScreenComponent
|
import im.vector.app.core.di.ScreenComponent
|
||||||
import im.vector.app.core.error.ErrorFormatter
|
|
||||||
import im.vector.app.core.extensions.setTextOrHide
|
import im.vector.app.core.extensions.setTextOrHide
|
||||||
import im.vector.app.core.platform.ButtonStateView
|
import im.vector.app.core.platform.ButtonStateView
|
||||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||||
import im.vector.app.core.utils.toast
|
import im.vector.app.core.utils.toast
|
||||||
import im.vector.app.databinding.BottomSheetInvitedToSpaceBinding
|
import im.vector.app.databinding.BottomSheetInvitedToSpaceBinding
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetInvitedToSpaceBinding>() {
|
class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetInvitedToSpaceBinding>(), SpaceInviteBottomSheetViewModel.Factory {
|
||||||
|
|
||||||
interface InteractionListener {
|
interface InteractionListener {
|
||||||
fun onAccept(spaceId: String)
|
fun spaceInviteBottomSheetOnAccept(spaceId: String)
|
||||||
fun onDecline(spaceId: String)
|
fun spaceInviteBottomSheetOnDecline(spaceId: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
var interactionListener: InteractionListener? = null
|
var interactionListener: InteractionListener? = null
|
||||||
@ -56,14 +57,14 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetIn
|
|||||||
val spaceId: String
|
val spaceId: String
|
||||||
) : Parcelable
|
) : Parcelable
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var activeSessionHolder: ActiveSessionHolder
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var avatarRenderer: AvatarRenderer
|
lateinit var avatarRenderer: AvatarRenderer
|
||||||
|
|
||||||
@Inject
|
private val viewModel: SpaceInviteBottomSheetViewModel by fragmentViewModel(SpaceInviteBottomSheetViewModel::class)
|
||||||
lateinit var errorFormatter: ErrorFormatter
|
|
||||||
|
@Inject lateinit var viewModelFactory: SpaceInviteBottomSheetViewModel.Factory
|
||||||
|
|
||||||
|
override fun create(initialState: SpaceInviteBottomSheetState) = viewModelFactory.create(initialState)
|
||||||
|
|
||||||
override fun injectWith(injector: ScreenComponent) {
|
override fun injectWith(injector: ScreenComponent) {
|
||||||
injector.inject(this)
|
injector.inject(this)
|
||||||
@ -75,13 +76,50 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetIn
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val session = activeSessionHolder.getSafeActiveSession() ?: return
|
|
||||||
|
|
||||||
val summary = session.getRoomSummary(inviteArgs.spaceId) ?: return Unit.also {
|
views.spaceCard.matrixToCardMainButton.callback = object : ButtonStateView.Callback {
|
||||||
dismiss()
|
override fun onButtonClicked() {
|
||||||
|
// quick local echo
|
||||||
|
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loading)
|
||||||
|
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
||||||
|
viewModel.handle(SpaceInviteBottomSheetAction.DoJoin)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRetryClicked() = onButtonClicked()
|
||||||
|
}
|
||||||
|
views.spaceCard.matrixToCardSecondaryButton.callback = object : ButtonStateView.Callback {
|
||||||
|
override fun onButtonClicked() {
|
||||||
|
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loading)
|
||||||
|
views.spaceCard.matrixToCardMainButton.button.isEnabled = true
|
||||||
|
viewModel.handle(SpaceInviteBottomSheetAction.DoReject)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRetryClicked() = onButtonClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
val inviter = summary.inviterId?.let { session.getUser(it) }?.toMatrixItem()
|
viewModel.observeViewEvents {
|
||||||
|
when (it) {
|
||||||
|
is SpaceInviteBottomSheetEvents.ShowError -> requireActivity().toast(it.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAttach(context: Context) {
|
||||||
|
super.onAttach(context)
|
||||||
|
if (context is InteractionListener) {
|
||||||
|
interactionListener = context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetach() {
|
||||||
|
interactionListener = null
|
||||||
|
super.onDetach()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(viewModel) { state ->
|
||||||
|
super.invalidate()
|
||||||
|
val summary = state.summary.invoke()
|
||||||
|
val inviter = state.inviterUser.invoke()?.toMatrixItem()
|
||||||
if (inviter != null) {
|
if (inviter != null) {
|
||||||
views.inviterAvatarImage.isVisible = true
|
views.inviterAvatarImage.isVisible = true
|
||||||
views.inviterText.isVisible = true
|
views.inviterText.isVisible = true
|
||||||
@ -96,85 +134,52 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetIn
|
|||||||
}
|
}
|
||||||
|
|
||||||
views.spaceCard.matrixToCardContentVisibility.isVisible = true
|
views.spaceCard.matrixToCardContentVisibility.isVisible = true
|
||||||
avatarRenderer.renderSpace(summary.toMatrixItem(), views.spaceCard.matrixToCardAvatar)
|
summary?.toMatrixItem()?.let { avatarRenderer.renderSpace(it, views.spaceCard.matrixToCardAvatar) }
|
||||||
views.spaceCard.matrixToCardNameText.text = summary.displayName
|
views.spaceCard.matrixToCardNameText.text = summary?.displayName
|
||||||
views.spaceCard.matrixToBetaTag.isVisible = true
|
views.spaceCard.matrixToBetaTag.isVisible = true
|
||||||
views.spaceCard.matrixToCardAliasText.setTextOrHide(summary.canonicalAlias)
|
views.spaceCard.matrixToCardAliasText.setTextOrHide(summary?.canonicalAlias)
|
||||||
views.spaceCard.matrixToCardDescText.setTextOrHide(summary.topic)
|
views.spaceCard.matrixToCardDescText.setTextOrHide(summary?.topic)
|
||||||
|
|
||||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Button)
|
|
||||||
views.spaceCard.matrixToCardMainButton.button.text = getString(R.string.accept)
|
views.spaceCard.matrixToCardMainButton.button.text = getString(R.string.accept)
|
||||||
views.spaceCard.matrixToCardMainButton.callback = object : ButtonStateView.Callback {
|
views.spaceCard.matrixToCardSecondaryButton.button.text = getString(R.string.decline)
|
||||||
override fun onButtonClicked() {
|
|
||||||
doJoin()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRetryClicked() {
|
when (state.joinActionState) {
|
||||||
doJoin()
|
Uninitialized -> {
|
||||||
|
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Button)
|
||||||
}
|
}
|
||||||
|
is Loading -> {
|
||||||
private fun doJoin() {
|
|
||||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loading)
|
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loading)
|
||||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = false
|
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = false
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
}
|
||||||
try {
|
is Success -> {
|
||||||
activeSessionHolder.getSafeActiveSession()?.getRoom(inviteArgs.spaceId)?.join()
|
interactionListener?.spaceInviteBottomSheetOnAccept(inviteArgs.spaceId)
|
||||||
withContext(Dispatchers.Main) {
|
dismiss()
|
||||||
if (!isAdded) return@withContext
|
}
|
||||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loaded)
|
is Fail -> {
|
||||||
views.spaceCard.matrixToCardSecondaryButton.isEnabled = true
|
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Error)
|
||||||
interactionListener?.onAccept(inviteArgs.spaceId)
|
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (!isAdded) return@withContext
|
|
||||||
requireActivity().toast(errorFormatter.toHumanReadable(failure))
|
|
||||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Error)
|
|
||||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Button)
|
when (state.rejectActionState) {
|
||||||
views.spaceCard.matrixToCardSecondaryButton.button.text = getString(R.string.reject)
|
Uninitialized -> {
|
||||||
views.spaceCard.matrixToCardSecondaryButton.callback = object : ButtonStateView.Callback {
|
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Button)
|
||||||
override fun onButtonClicked() {
|
|
||||||
doReject()
|
|
||||||
}
|
}
|
||||||
|
is Loading -> {
|
||||||
override fun onRetryClicked() {
|
|
||||||
doReject()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun doReject() {
|
|
||||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loading)
|
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loading)
|
||||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = false
|
views.spaceCard.matrixToCardMainButton.button.isEnabled = false
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
}
|
||||||
try {
|
is Success -> {
|
||||||
activeSessionHolder.getSafeActiveSession()?.getRoom(inviteArgs.spaceId)?.leave()
|
interactionListener?.spaceInviteBottomSheetOnDecline(inviteArgs.spaceId)
|
||||||
withContext(Dispatchers.Main) {
|
dismiss()
|
||||||
if (!isAdded) return@withContext
|
}
|
||||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loaded)
|
is Fail -> {
|
||||||
views.spaceCard.matrixToCardMainButton.button.isEnabled = true
|
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Error)
|
||||||
interactionListener?.onDecline(inviteArgs.spaceId)
|
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
} catch (failure: Throwable) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (!isAdded) return@withContext
|
|
||||||
requireActivity().toast(errorFormatter.toHumanReadable(failure))
|
|
||||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Error)
|
|
||||||
views.spaceCard.matrixToCardMainButton.button.isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val memberCount = summary.otherMemberIds.size
|
val memberCount = summary?.otherMemberIds?.size ?: 0
|
||||||
if (memberCount != 0) {
|
if (memberCount != 0) {
|
||||||
views.spaceCard.matrixToMemberPills.isVisible = true
|
views.spaceCard.matrixToMemberPills.isVisible = true
|
||||||
views.spaceCard.spaceChildMemberCountText.text = resources.getQuantityString(R.plurals.room_title_members, memberCount, memberCount)
|
views.spaceCard.spaceChildMemberCountText.text = resources.getQuantityString(R.plurals.room_title_members, memberCount, memberCount)
|
||||||
@ -183,12 +188,7 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetIn
|
|||||||
views.spaceCard.matrixToMemberPills.isVisible = false
|
views.spaceCard.matrixToMemberPills.isVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
val knownMembers = summary.otherMemberIds.filter {
|
val peopleYouKnow = state.peopleYouKnow.invoke().orEmpty()
|
||||||
session.getExistingDirectRoomWithUser(it) != null
|
|
||||||
}.mapNotNull { session.getUser(it) }
|
|
||||||
// put one with avatar first, and take 5
|
|
||||||
val peopleYouKnow = (knownMembers.filter { it.avatarUrl != null } + knownMembers.filter { it.avatarUrl == null })
|
|
||||||
.take(5)
|
|
||||||
|
|
||||||
val images = listOf(
|
val images = listOf(
|
||||||
views.spaceCard.knownMember1,
|
views.spaceCard.knownMember1,
|
||||||
@ -220,10 +220,9 @@ class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetIn
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun newInstance(spaceId: String, interactionListener: InteractionListener)
|
fun newInstance(spaceId: String)
|
||||||
: SpaceInviteBottomSheet {
|
: SpaceInviteBottomSheet {
|
||||||
return SpaceInviteBottomSheet().apply {
|
return SpaceInviteBottomSheet().apply {
|
||||||
this.interactionListener = interactionListener
|
|
||||||
setArguments(Args(spaceId))
|
setArguments(Args(spaceId))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.spaces.invite
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewModelAction
|
||||||
|
|
||||||
|
sealed class SpaceInviteBottomSheetAction : VectorViewModelAction {
|
||||||
|
object DoJoin : SpaceInviteBottomSheetAction()
|
||||||
|
object DoReject : SpaceInviteBottomSheetAction()
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.spaces.invite
|
||||||
|
|
||||||
|
import im.vector.app.core.platform.VectorViewEvents
|
||||||
|
|
||||||
|
sealed class SpaceInviteBottomSheetEvents : VectorViewEvents {
|
||||||
|
data class ShowError(val message: String) : SpaceInviteBottomSheetEvents()
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.spaces.invite
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.Async
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import org.matrix.android.sdk.api.session.room.model.RoomSummary
|
||||||
|
import org.matrix.android.sdk.api.session.user.model.User
|
||||||
|
|
||||||
|
data class SpaceInviteBottomSheetState(
|
||||||
|
val spaceId: String,
|
||||||
|
val summary: Async<RoomSummary> = Uninitialized,
|
||||||
|
val inviterUser: Async<User> = Uninitialized,
|
||||||
|
val peopleYouKnow: Async<List<User>> = Uninitialized,
|
||||||
|
val joinActionState: Async<Unit> = Uninitialized,
|
||||||
|
val rejectActionState: Async<Unit> = Uninitialized
|
||||||
|
) : MvRxState {
|
||||||
|
constructor(args: SpaceInviteBottomSheet.Args) : this(
|
||||||
|
spaceId = args.spaceId
|
||||||
|
)
|
||||||
|
}
|
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2021 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.spaces.invite
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.ActivityViewModelContext
|
||||||
|
import com.airbnb.mvrx.Fail
|
||||||
|
import com.airbnb.mvrx.FragmentViewModelContext
|
||||||
|
import com.airbnb.mvrx.Loading
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.Success
|
||||||
|
import com.airbnb.mvrx.Uninitialized
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import dagger.assisted.Assisted
|
||||||
|
import dagger.assisted.AssistedFactory
|
||||||
|
import dagger.assisted.AssistedInject
|
||||||
|
import im.vector.app.core.error.ErrorFormatter
|
||||||
|
import im.vector.app.core.platform.VectorViewModel
|
||||||
|
import im.vector.app.features.session.coroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.matrix.android.sdk.api.session.Session
|
||||||
|
|
||||||
|
class SpaceInviteBottomSheetViewModel @AssistedInject constructor(
|
||||||
|
@Assisted private val initialState: SpaceInviteBottomSheetState,
|
||||||
|
private val session: Session,
|
||||||
|
private val errorFormatter: ErrorFormatter
|
||||||
|
) : VectorViewModel<SpaceInviteBottomSheetState, SpaceInviteBottomSheetAction, SpaceInviteBottomSheetEvents>(initialState) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
session.getRoomSummary(initialState.spaceId)?.let { roomSummary ->
|
||||||
|
|
||||||
|
val knownMembers = roomSummary.otherMemberIds.filter {
|
||||||
|
session.getExistingDirectRoomWithUser(it) != null
|
||||||
|
}.mapNotNull { session.getUser(it) }
|
||||||
|
// put one with avatar first, and take 5
|
||||||
|
val peopleYouKnow = (knownMembers.filter { it.avatarUrl != null } + knownMembers.filter { it.avatarUrl == null })
|
||||||
|
.take(5)
|
||||||
|
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
summary = Success(roomSummary),
|
||||||
|
inviterUser = roomSummary.inviterId?.let { session.getUser(it) }?.let { Success(it) } ?: Uninitialized,
|
||||||
|
peopleYouKnow = Success(peopleYouKnow)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedFactory
|
||||||
|
interface Factory {
|
||||||
|
fun create(initialState: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<SpaceInviteBottomSheetViewModel, SpaceInviteBottomSheetState> {
|
||||||
|
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: SpaceInviteBottomSheetState): SpaceInviteBottomSheetViewModel? {
|
||||||
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun handle(action: SpaceInviteBottomSheetAction) {
|
||||||
|
when (action) {
|
||||||
|
SpaceInviteBottomSheetAction.DoJoin -> {
|
||||||
|
setState { copy(joinActionState = Loading()) }
|
||||||
|
session.coroutineScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
session.getRoom(initialState.spaceId)?.join()
|
||||||
|
setState { copy(joinActionState = Success(Unit)) }
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
setState { copy(joinActionState = Fail(failure)) }
|
||||||
|
_viewEvents.post(SpaceInviteBottomSheetEvents.ShowError(errorFormatter.toHumanReadable(failure)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SpaceInviteBottomSheetAction.DoReject -> {
|
||||||
|
setState { copy(rejectActionState = Loading()) }
|
||||||
|
session.coroutineScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
session.getRoom(initialState.spaceId)?.leave()
|
||||||
|
setState { copy(rejectActionState = Success(Unit)) }
|
||||||
|
} catch (failure: Throwable) {
|
||||||
|
setState { copy(rejectActionState = Fail(failure)) }
|
||||||
|
_viewEvents.post(SpaceInviteBottomSheetEvents.ShowError(errorFormatter.toHumanReadable(failure)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user