mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 02:15:35 +03:00
Merge pull request #3259 from vector-im/feature/bca/spaces_advertise_beta
Invite bottom sheet + fixes + beta tag
This commit is contained in:
commit
b09e509db7
23 changed files with 808 additions and 230 deletions
|
@ -24,6 +24,7 @@ import im.vector.app.core.di.ActiveSessionHolder
|
|||
import im.vector.app.core.utils.BehaviorDataSource
|
||||
import im.vector.app.features.ui.UiStateRepository
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
|
@ -68,7 +69,7 @@ class AppStateHandler @Inject constructor(
|
|||
val spaceSum = spaceId?.let { uSession?.getRoomSummary(spaceId) }
|
||||
selectedSpaceDataSource.post(Option.just(RoomGroupingMethod.BySpace(spaceSum)))
|
||||
if (spaceId != null) {
|
||||
GlobalScope.launch {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
tryOrNull {
|
||||
uSession?.getRoom(spaceId)?.loadRoomMembersIfNeeded()
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ import im.vector.app.features.spaces.InviteRoomSpaceChooserBottomSheet
|
|||
import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
||||
import im.vector.app.features.spaces.SpaceCreationActivity
|
||||
import im.vector.app.features.spaces.SpaceExploreActivity
|
||||
import im.vector.app.features.spaces.invite.SpaceInviteBottomSheet
|
||||
import im.vector.app.features.spaces.SpaceSettingsMenuBottomSheet
|
||||
import im.vector.app.features.spaces.manage.SpaceManageActivity
|
||||
import im.vector.app.features.terms.ReviewTermsActivity
|
||||
|
@ -185,6 +186,7 @@ interface ScreenComponent {
|
|||
fun inject(bottomSheet: ShareSpaceBottomSheet)
|
||||
fun inject(bottomSheet: SpaceSettingsMenuBottomSheet)
|
||||
fun inject(bottomSheet: InviteRoomSpaceChooserBottomSheet)
|
||||
fun inject(bottomSheet: SpaceInviteBottomSheet)
|
||||
|
||||
/* ==========================================================================================
|
||||
* Others
|
||||
|
|
|
@ -62,6 +62,7 @@ import im.vector.app.features.spaces.ShareSpaceBottomSheet
|
|||
import im.vector.app.features.spaces.SpaceCreationActivity
|
||||
import im.vector.app.features.spaces.SpacePreviewActivity
|
||||
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.workers.signout.ServerBackupStatusViewModel
|
||||
import im.vector.app.features.workers.signout.ServerBackupStatusViewState
|
||||
|
@ -88,7 +89,8 @@ class HomeActivity :
|
|||
UnknownDeviceDetectorSharedViewModel.Factory,
|
||||
ServerBackupStatusViewModel.Factory,
|
||||
UnreadMessagesSharedViewModel.Factory,
|
||||
NavigationInterceptor {
|
||||
NavigationInterceptor,
|
||||
SpaceInviteBottomSheet.InteractionListener {
|
||||
|
||||
private lateinit var sharedActionViewModel: HomeSharedActionViewModel
|
||||
|
||||
|
@ -210,6 +212,10 @@ class HomeActivity :
|
|||
})
|
||||
.show(supportFragmentManager, "SPACE_SETTINGS")
|
||||
}
|
||||
is HomeActivitySharedAction.OpenSpaceInvite -> {
|
||||
SpaceInviteBottomSheet.newInstance(sharedAction.spaceId)
|
||||
.show(supportFragmentManager, "SPACE_INVITE")
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
|
@ -514,6 +520,14 @@ class HomeActivity :
|
|||
return true
|
||||
}
|
||||
|
||||
override fun spaceInviteBottomSheetOnAccept(spaceId: String) {
|
||||
navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None)
|
||||
}
|
||||
|
||||
override fun spaceInviteBottomSheetOnDecline(spaceId: String) {
|
||||
// nop
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context, clearNotification: Boolean = false, accountCreation: Boolean = false): Intent {
|
||||
val args = HomeActivityArgs(
|
||||
|
|
|
@ -27,5 +27,6 @@ sealed class HomeActivitySharedAction : VectorSharedAction {
|
|||
data class OpenGroup(val clearFragment: Boolean) : HomeActivitySharedAction()
|
||||
object AddSpace : HomeActivitySharedAction()
|
||||
data class OpenSpacePreview(val spaceId: String) : HomeActivitySharedAction()
|
||||
data class OpenSpaceInvite(val spaceId: String) : HomeActivitySharedAction()
|
||||
data class ShowSpaceSettings(val spaceId: String) : HomeActivitySharedAction()
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Fail
|
||||
|
@ -71,8 +72,10 @@ class MatrixToRoomSpaceFragment @Inject constructor(
|
|||
is RoomInfoResult.FullInfo -> {
|
||||
val matrixItem = peek.roomItem
|
||||
if (peek.roomType == RoomType.SPACE) {
|
||||
views.matrixToBetaTag.isVisible = true
|
||||
avatarRenderer.renderSpace(matrixItem, views.matrixToCardAvatar)
|
||||
} else {
|
||||
views.matrixToBetaTag.isVisible = false
|
||||
avatarRenderer.render(matrixItem, views.matrixToCardAvatar)
|
||||
}
|
||||
views.matrixToCardNameText.setTextOrHide(peek.name)
|
||||
|
@ -97,19 +100,19 @@ class MatrixToRoomSpaceFragment @Inject constructor(
|
|||
Membership.LEAVE,
|
||||
Membership.NONE -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardMainButton.text = getString(joinTextRes)
|
||||
views.matrixToCardMainButton.button.text = getString(joinTextRes)
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
Membership.INVITE -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardSecondaryButton.isVisible = true
|
||||
views.matrixToCardMainButton.text = getString(joinTextRes)
|
||||
views.matrixToCardSecondaryButton.text = getString(R.string.decline)
|
||||
views.matrixToCardMainButton.button.text = getString(joinTextRes)
|
||||
views.matrixToCardSecondaryButton.button.text = getString(R.string.decline)
|
||||
}
|
||||
Membership.JOIN -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
views.matrixToCardMainButton.text = getString(R.string.action_open)
|
||||
views.matrixToCardMainButton.button.text = getString(R.string.action_open)
|
||||
}
|
||||
Membership.KNOCK,
|
||||
Membership.BAN -> {
|
||||
|
@ -126,7 +129,7 @@ class MatrixToRoomSpaceFragment @Inject constructor(
|
|||
views.matrixToMemberPills.isVisible = false
|
||||
views.matrixToCardDescText.setTextOrHide(getString(R.string.room_preview_no_preview))
|
||||
|
||||
views.matrixToCardMainButton.text = getString(R.string.join_anyway)
|
||||
views.matrixToCardMainButton.button.text = getString(R.string.join_anyway)
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
RoomInfoResult.NotFound -> {
|
||||
|
@ -156,12 +159,10 @@ class MatrixToRoomSpaceFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
val images = listOf(views.knownMember1, views.knownMember2, views.knownMember3, views.knownMember4, views.knownMember5)
|
||||
.onEach { it.isGone = true }
|
||||
when (state.peopleYouKnow) {
|
||||
is Success -> {
|
||||
views.matrixToCardPeopleYouKnowVisibility.isVisible = true
|
||||
val images = listOf(views.knownMember1, views.knownMember2, views.knownMember3, views.knownMember4, views.knownMember5)
|
||||
.onEach { it.isVisible = false }
|
||||
|
||||
val someYouKnow = state.peopleYouKnow.invoke()
|
||||
someYouKnow.forEachIndexed { index, item ->
|
||||
images[index].isVisible = true
|
||||
|
@ -175,7 +176,7 @@ class MatrixToRoomSpaceFragment @Inject constructor(
|
|||
)
|
||||
}
|
||||
else -> {
|
||||
views.matrixToCardPeopleYouKnowVisibility.isVisible = false
|
||||
views.peopleYouMayKnowText.isVisible = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class SpaceListFragment @Inject constructor(
|
|||
is SpaceListViewEvents.OpenSpace -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup(it.groupingMethodHasChanged))
|
||||
is SpaceListViewEvents.AddSpace -> sharedActionViewModel.post(HomeActivitySharedAction.AddSpace)
|
||||
is SpaceListViewEvents.OpenGroup -> sharedActionViewModel.post(HomeActivitySharedAction.OpenGroup(it.groupingMethodHasChanged))
|
||||
is SpaceListViewEvents.OpenSpaceInvite -> sharedActionViewModel.post(HomeActivitySharedAction.OpenSpaceInvite(it.id))
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import im.vector.app.core.platform.VectorViewEvents
|
|||
sealed class SpaceListViewEvents : VectorViewEvents {
|
||||
data class OpenSpace(val groupingMethodHasChanged: Boolean) : SpaceListViewEvents()
|
||||
data class OpenSpaceSummary(val id: String) : SpaceListViewEvents()
|
||||
data class OpenSpaceInvite(val id: String) : SpaceListViewEvents()
|
||||
object AddSpace : SpaceListViewEvents()
|
||||
data class OpenGroup(val groupingMethodHasChanged: Boolean) : SpaceListViewEvents()
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ class SpacesListViewModel @AssistedInject constructor(@Assisted initialState: Sp
|
|||
}
|
||||
|
||||
private fun handleSelectSpaceInvite(action: SpaceListAction.OpenSpaceInvite) {
|
||||
_viewEvents.post(SpaceListViewEvents.OpenSpaceSummary(action.spaceSummary.roomId))
|
||||
_viewEvents.post(SpaceListViewEvents.OpenSpaceInvite(action.spaceSummary.roomId))
|
||||
}
|
||||
|
||||
private fun handleToggleExpand(action: SpaceListAction.ToggleExpand) = withState { state ->
|
||||
|
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* 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 android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isGone
|
||||
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.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.di.ScreenComponent
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.ButtonStateView
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.BottomSheetInvitedToSpaceBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import javax.inject.Inject
|
||||
|
||||
class SpaceInviteBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetInvitedToSpaceBinding>(), SpaceInviteBottomSheetViewModel.Factory {
|
||||
|
||||
interface InteractionListener {
|
||||
fun spaceInviteBottomSheetOnAccept(spaceId: String)
|
||||
fun spaceInviteBottomSheetOnDecline(spaceId: String)
|
||||
}
|
||||
|
||||
var interactionListener: InteractionListener? = null
|
||||
|
||||
@Parcelize
|
||||
data class Args(
|
||||
val spaceId: String
|
||||
) : Parcelable
|
||||
|
||||
@Inject
|
||||
lateinit var avatarRenderer: AvatarRenderer
|
||||
|
||||
private val viewModel: SpaceInviteBottomSheetViewModel by fragmentViewModel(SpaceInviteBottomSheetViewModel::class)
|
||||
|
||||
@Inject lateinit var viewModelFactory: SpaceInviteBottomSheetViewModel.Factory
|
||||
|
||||
override fun create(initialState: SpaceInviteBottomSheetState) = viewModelFactory.create(initialState)
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
}
|
||||
|
||||
override val showExpanded = true
|
||||
|
||||
private val inviteArgs: Args by args()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
views.spaceCard.matrixToCardMainButton.callback = object : ButtonStateView.Callback {
|
||||
override fun onButtonClicked() {
|
||||
// quick local echo
|
||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loading)
|
||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = false
|
||||
viewModel.handle(SpaceInviteBottomSheetAction.DoJoin)
|
||||
}
|
||||
|
||||
override fun onRetryClicked() = onButtonClicked()
|
||||
}
|
||||
views.spaceCard.matrixToCardSecondaryButton.callback = object : ButtonStateView.Callback {
|
||||
override fun onButtonClicked() {
|
||||
views.spaceCard.matrixToCardMainButton.button.isEnabled = false
|
||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loading)
|
||||
viewModel.handle(SpaceInviteBottomSheetAction.DoReject)
|
||||
}
|
||||
|
||||
override fun onRetryClicked() = onButtonClicked()
|
||||
}
|
||||
|
||||
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) {
|
||||
views.inviterAvatarImage.isVisible = true
|
||||
views.inviterText.isVisible = true
|
||||
views.inviterMxid.isVisible = true
|
||||
avatarRenderer.render(inviter, views.inviterAvatarImage)
|
||||
views.inviterText.text = getString(R.string.user_invites_you, inviter.getBestName())
|
||||
views.inviterMxid.text = inviter.id
|
||||
} else {
|
||||
views.inviterAvatarImage.isVisible = false
|
||||
views.inviterText.isVisible = false
|
||||
views.inviterMxid.isVisible = false
|
||||
}
|
||||
|
||||
views.spaceCard.matrixToCardContentVisibility.isVisible = true
|
||||
summary?.toMatrixItem()?.let { avatarRenderer.renderSpace(it, views.spaceCard.matrixToCardAvatar) }
|
||||
views.spaceCard.matrixToCardNameText.text = summary?.displayName
|
||||
views.spaceCard.matrixToBetaTag.isVisible = true
|
||||
views.spaceCard.matrixToCardAliasText.setTextOrHide(summary?.canonicalAlias)
|
||||
views.spaceCard.matrixToCardDescText.setTextOrHide(summary?.topic)
|
||||
|
||||
views.spaceCard.matrixToCardMainButton.button.text = getString(R.string.accept)
|
||||
views.spaceCard.matrixToCardSecondaryButton.button.text = getString(R.string.decline)
|
||||
|
||||
when (state.joinActionState) {
|
||||
Uninitialized -> {
|
||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Button)
|
||||
}
|
||||
is Loading -> {
|
||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Loading)
|
||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = false
|
||||
}
|
||||
is Success -> {
|
||||
interactionListener?.spaceInviteBottomSheetOnAccept(inviteArgs.spaceId)
|
||||
dismiss()
|
||||
}
|
||||
is Fail -> {
|
||||
views.spaceCard.matrixToCardMainButton.render(ButtonStateView.State.Error)
|
||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
when (state.rejectActionState) {
|
||||
Uninitialized -> {
|
||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Button)
|
||||
}
|
||||
is Loading -> {
|
||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Loading)
|
||||
views.spaceCard.matrixToCardMainButton.button.isEnabled = false
|
||||
}
|
||||
is Success -> {
|
||||
interactionListener?.spaceInviteBottomSheetOnDecline(inviteArgs.spaceId)
|
||||
dismiss()
|
||||
}
|
||||
is Fail -> {
|
||||
views.spaceCard.matrixToCardSecondaryButton.render(ButtonStateView.State.Error)
|
||||
views.spaceCard.matrixToCardSecondaryButton.button.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
val memberCount = summary?.otherMemberIds?.size ?: 0
|
||||
if (memberCount != 0) {
|
||||
views.spaceCard.matrixToMemberPills.isVisible = true
|
||||
views.spaceCard.spaceChildMemberCountText.text = resources.getQuantityString(R.plurals.room_title_members, memberCount, memberCount)
|
||||
} else {
|
||||
// hide the pill
|
||||
views.spaceCard.matrixToMemberPills.isVisible = false
|
||||
}
|
||||
|
||||
val peopleYouKnow = state.peopleYouKnow.invoke().orEmpty()
|
||||
|
||||
val images = listOf(
|
||||
views.spaceCard.knownMember1,
|
||||
views.spaceCard.knownMember2,
|
||||
views.spaceCard.knownMember3,
|
||||
views.spaceCard.knownMember4,
|
||||
views.spaceCard.knownMember5
|
||||
).onEach { it.isGone = true }
|
||||
|
||||
if (peopleYouKnow.isEmpty()) {
|
||||
views.spaceCard.peopleYouMayKnowText.isVisible = false
|
||||
} else {
|
||||
peopleYouKnow.forEachIndexed { index, item ->
|
||||
images[index].isVisible = true
|
||||
avatarRenderer.render(item.toMatrixItem(), images[index])
|
||||
}
|
||||
views.spaceCard.peopleYouMayKnowText.setTextOrHide(
|
||||
resources.getQuantityString(R.plurals.space_people_you_know,
|
||||
peopleYouKnow.count(),
|
||||
peopleYouKnow.count()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetInvitedToSpaceBinding {
|
||||
return BottomSheetInvitedToSpaceBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(spaceId: String)
|
||||
: SpaceInviteBottomSheet {
|
||||
return SpaceInviteBottomSheet().apply {
|
||||
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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -37,16 +37,15 @@ class SpacePreviewController @Inject constructor(
|
|||
var interactionListener: InteractionListener? = null
|
||||
|
||||
override fun buildModels(data: SpacePreviewState?) {
|
||||
val result = data?.childInfoList?.invoke() ?: return
|
||||
|
||||
val memberCount = data.spaceInfo.invoke()?.memberCount ?: 0
|
||||
val memberCount = data?.spaceInfo?.invoke()?.memberCount ?: 0
|
||||
|
||||
spaceTopSummaryItem {
|
||||
id("info")
|
||||
formattedMemberCount(stringProvider.getQuantityString(R.plurals.room_title_members, memberCount, memberCount))
|
||||
topic(data.spaceInfo.invoke()?.topic ?: data.topic ?: "")
|
||||
topic(data?.spaceInfo?.invoke()?.topic ?: data?.topic ?: "")
|
||||
}
|
||||
|
||||
val result = data?.childInfoList?.invoke() ?: return
|
||||
if (result.isNotEmpty()) {
|
||||
genericItemHeader {
|
||||
id("header_rooms")
|
||||
|
|
|
@ -119,14 +119,17 @@ class SpacePreviewFragment @Inject constructor(
|
|||
}
|
||||
}
|
||||
updateToolbar(it)
|
||||
|
||||
when (it.inviteTermination) {
|
||||
is Loading -> sharedActionViewModel.post(SpacePreviewSharedAction.ShowModalLoading)
|
||||
else -> sharedActionViewModel.post(SpacePreviewSharedAction.HideModalLoading)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleViewEvents(viewEvents: SpacePreviewViewEvents) {
|
||||
when (viewEvents) {
|
||||
SpacePreviewViewEvents.Dismiss -> {
|
||||
}
|
||||
SpacePreviewViewEvents.StartJoining -> {
|
||||
sharedActionViewModel.post(SpacePreviewSharedAction.ShowModalLoading)
|
||||
sharedActionViewModel.post(SpacePreviewSharedAction.DismissAction)
|
||||
}
|
||||
SpacePreviewViewEvents.JoinSuccess -> {
|
||||
sharedActionViewModel.post(SpacePreviewSharedAction.HideModalLoading)
|
||||
|
|
|
@ -26,7 +26,8 @@ data class SpacePreviewState(
|
|||
val topic: String? = null,
|
||||
val avatarUrl: String? = null,
|
||||
val spaceInfo: Async<ChildInfo> = Uninitialized,
|
||||
val childInfoList: Async<List<ChildInfo>> = Uninitialized
|
||||
val childInfoList: Async<List<ChildInfo>> = Uninitialized,
|
||||
val inviteTermination: Async<Unit> = Uninitialized
|
||||
) : MvRxState {
|
||||
constructor(args: SpacePreviewArgs) : this(idOrAlias = args.idOrAlias)
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import im.vector.app.core.platform.VectorViewEvents
|
|||
|
||||
sealed class SpacePreviewViewEvents : VectorViewEvents {
|
||||
object Dismiss: SpacePreviewViewEvents()
|
||||
object StartJoining: SpacePreviewViewEvents()
|
||||
object JoinSuccess: SpacePreviewViewEvents()
|
||||
data class JoinFailure(val message: String?): SpacePreviewViewEvents()
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ 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 kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -41,6 +42,7 @@ import timber.log.Timber
|
|||
|
||||
class SpacePreviewViewModel @AssistedInject constructor(
|
||||
@Assisted private val initialState: SpacePreviewState,
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val session: Session
|
||||
) : VectorViewModel<SpacePreviewState, SpacePreviewViewAction, SpacePreviewViewEvents>(initialState) {
|
||||
|
||||
|
@ -80,13 +82,15 @@ class SpacePreviewViewModel @AssistedInject constructor(
|
|||
|
||||
private fun handleDismissInvite() {
|
||||
// Here we need to join the space himself as well as the default rooms in that space
|
||||
// TODO modal loading
|
||||
setState { copy(inviteTermination = Loading()) }
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
session.spaceService().rejectInvite(initialState.idOrAlias, null)
|
||||
} catch (failure: Throwable) {
|
||||
Timber.e(failure, "## Space: Failed to reject invite")
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinFailure(errorFormatter.toHumanReadable(failure)))
|
||||
}
|
||||
setState { copy(inviteTermination = Uninitialized) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,18 +102,25 @@ class SpacePreviewViewModel @AssistedInject constructor(
|
|||
val spaceVia = spaceInfo?.viaServers ?: emptyList()
|
||||
|
||||
// trigger modal loading
|
||||
_viewEvents.post(SpacePreviewViewEvents.StartJoining)
|
||||
setState { copy(inviteTermination = Loading()) }
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val joinResult = session.spaceService().joinSpace(initialState.idOrAlias, null, spaceVia)
|
||||
when (joinResult) {
|
||||
JoinSpaceResult.Success,
|
||||
is JoinSpaceResult.PartialSuccess -> {
|
||||
// For now we don't handle partial success, it's just success
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinSuccess)
|
||||
}
|
||||
is JoinSpaceResult.Fail -> {
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinFailure(joinResult.error.toString()))
|
||||
try {
|
||||
val joinResult = session.spaceService().joinSpace(initialState.idOrAlias, null, spaceVia)
|
||||
setState { copy(inviteTermination = Uninitialized) }
|
||||
when (joinResult) {
|
||||
JoinSpaceResult.Success,
|
||||
is JoinSpaceResult.PartialSuccess -> {
|
||||
// For now we don't handle partial success, it's just success
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinSuccess)
|
||||
}
|
||||
is JoinSpaceResult.Fail -> {
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinFailure(errorFormatter.toHumanReadable(joinResult.error)))
|
||||
}
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
// should not throw
|
||||
Timber.w(failure, "## Failed to join space")
|
||||
_viewEvents.post(SpacePreviewViewEvents.JoinFailure(errorFormatter.toHumanReadable(failure)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +232,21 @@ class SpacePreviewViewModel @AssistedInject constructor(
|
|||
}
|
||||
} catch (failure: Throwable) {
|
||||
setState {
|
||||
copy(spaceInfo = Fail(failure), childInfoList = Fail(failure))
|
||||
copy(
|
||||
spaceInfo = session.getRoomSummary(initialState.idOrAlias)?.let {
|
||||
Success(
|
||||
ChildInfo(
|
||||
roomId = it.roomId,
|
||||
avatarUrl = it.avatarUrl,
|
||||
name = it.displayName,
|
||||
topic = it.topic,
|
||||
memberCount = it.joinedMembersCount,
|
||||
isSubSpace = false,
|
||||
viaServers = null,
|
||||
children = Uninitialized
|
||||
)
|
||||
)
|
||||
} ?: Fail(failure), childInfoList = Fail(failure))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
76
vector/src/main/res/layout/bottom_sheet_invited_to_space.xml
Normal file
76
vector/src/main/res/layout/bottom_sheet_invited_to_space.xml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/bottomSheetScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true"
|
||||
android:background="?riotx_bottom_sheet_background"
|
||||
android:fadeScrollbars="false"
|
||||
android:scrollbars="vertical">
|
||||
|
||||
<!-- Inviter info-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/inviterAvatarImage"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
android:transitionName="profile"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inviterText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/inviterAvatarImage"
|
||||
app:layout_constraintTop_toTopOf="@id/inviterAvatarImage"
|
||||
tools:text="@string/user_invites_you" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/inviterMxid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/inviterAvatarImage"
|
||||
app:layout_constraintTop_toBottomOf="@id/inviterText"
|
||||
tools:text="@sample/matrix.json/data/mxid" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?attr/vctr_list_divider_color" />
|
||||
|
||||
<include
|
||||
android:id="@+id/spaceCard"
|
||||
layout="@layout/fragment_matrix_to_room_space_card" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
|
@ -1,224 +1,257 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="200dp"
|
||||
android:padding="16dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/matrixToCardAvatar"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:contentDescription="@string/avatar"
|
||||
android:elevation="4dp"
|
||||
android:transitionName="profile"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardNameText"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/matrixToCardContentVisibility"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@+id/matrixToCardAvatar"
|
||||
tools:text="@sample/matrix.json/data/roomName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardAliasText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
android:minHeight="200dp"
|
||||
android:padding="16dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardNameText"
|
||||
app:layout_goneMarginTop="0dp"
|
||||
tools:text="@sample/matrix.json/data/roomAlias" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/matrixToMemberPills"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/pill_receipt"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardAliasText">
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/spaceChildMemberCountIcon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_room_profile_member_list"
|
||||
app:tint="?riotx_text_primary"
|
||||
tools:ignore="MissingPrefix" />
|
||||
android:id="@+id/matrixToCardAvatar"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
android:elevation="4dp"
|
||||
android:transitionName="profile"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/spaceChildMemberCountText"
|
||||
<ImageView
|
||||
android:id="@+id/matrixToBetaTag"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_beta_pill"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardNameText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_primary"
|
||||
tools:text="123 members" />
|
||||
</LinearLayout>
|
||||
android:textSize="15sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintTop_toBottomOf="@+id/matrixToCardAvatar"
|
||||
tools:text="@sample/matrix.json/data/roomName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardDescText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToMemberPills"
|
||||
tools:text="@sample/matrix.json/data/roomTopic" />
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardAliasText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardNameText"
|
||||
app:layout_goneMarginTop="0dp"
|
||||
tools:text="@sample/matrix.json/data/roomAlias" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember5"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember4"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<LinearLayout
|
||||
android:id="@+id/matrixToMemberPills"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="@drawable/pill_receipt"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardAliasText">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember4"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember3"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<ImageView
|
||||
android:id="@+id/spaceChildMemberCountIcon"
|
||||
android:layout_width="18dp"
|
||||
android:layout_height="18dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_room_profile_member_list"
|
||||
app:tint="?riotx_text_primary"
|
||||
tools:ignore="MissingPrefix" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember3"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember2"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<TextView
|
||||
android:id="@+id/spaceChildMemberCountText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_primary"
|
||||
tools:text="123 members" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember2"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember1"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardDescText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="textStart"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToMemberPills"
|
||||
tools:text="@sample/matrix.json/data/roomTopic" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember1"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardDescText"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
<ImageView
|
||||
android:id="@+id/knownMember5"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember4"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/peopleYouMayKnowText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/knownMember1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/knownMember5"
|
||||
app:layout_constraintTop_toTopOf="@id/knownMember1"
|
||||
tools:text="7 people you may know" />
|
||||
<ImageView
|
||||
android:id="@+id/knownMember4"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember3"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars"
|
||||
tools:visibility="gone" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/matrixToCardMainButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/knownMember1"
|
||||
app:layout_constraintWidth_max="400dp"
|
||||
tools:text="@string/join" />
|
||||
<ImageView
|
||||
android:id="@+id/knownMember3"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember2"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/matrixToCardSecondaryButton"
|
||||
style="@style/VectorButtonStyleOutlined"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
android:textAllCaps="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardMainButton"
|
||||
app:layout_constraintWidth_max="400dp"
|
||||
tools:text="@string/dismiss" />
|
||||
<ImageView
|
||||
android:id="@+id/knownMember2"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintCircle="@id/knownMember1"
|
||||
app:layout_constraintCircleAngle="90"
|
||||
app:layout_constraintCircleRadius="20dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/knownMember1"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:contentDescription="@string/avatar"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardDescText"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/peopleYouMayKnowText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/knownMember1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/knownMember5"
|
||||
app:layout_constraintTop_toTopOf="@id/knownMember1"
|
||||
tools:text="7 people you may know" />
|
||||
|
||||
<im.vector.app.core.platform.ButtonStateView
|
||||
android:id="@+id/matrixToCardMainButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
app:bsv_button_text="@string/accept"
|
||||
app:bsv_loaded_image_src="@drawable/ic_tick"
|
||||
app:bsv_use_flat_button="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/knownMember1"
|
||||
app:layout_constraintWidth_max="400dp" />
|
||||
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:id="@+id/matrixToCardMainButton"-->
|
||||
<!-- android:layout_width="0dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="16dp"-->
|
||||
<!-- android:layout_marginBottom="@dimen/layout_vertical_margin_big"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@id/knownMember1"-->
|
||||
<!-- app:layout_constraintWidth_max="400dp"-->
|
||||
<!-- tools:text="@string/join" />-->
|
||||
|
||||
<!-- <com.google.android.material.button.MaterialButton-->
|
||||
<!-- android:id="@+id/matrixToCardSecondaryButton"-->
|
||||
<!-- style="@style/VectorButtonStyleOutlined"-->
|
||||
<!-- android:layout_width="0dp"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="8dp"-->
|
||||
<!-- android:layout_marginBottom="@dimen/layout_vertical_margin_big"-->
|
||||
<!-- android:textAllCaps="true"-->
|
||||
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
|
||||
<!-- app:layout_constraintEnd_toEndOf="parent"-->
|
||||
<!-- app:layout_constraintStart_toStartOf="parent"-->
|
||||
<!-- app:layout_constraintTop_toBottomOf="@id/matrixToCardMainButton"-->
|
||||
<!-- app:layout_constraintWidth_max="400dp"-->
|
||||
<!-- tools:text="@string/dismiss" />-->
|
||||
|
||||
<im.vector.app.core.platform.ButtonStateView
|
||||
android:id="@+id/matrixToCardSecondaryButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
app:bsv_button_text="@string/dismiss"
|
||||
app:bsv_loaded_image_src="@drawable/ic_tick"
|
||||
app:bsv_use_flat_button="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardMainButton"
|
||||
app:layout_constraintWidth_max="400dp" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/matrixToCardButtonLoading"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/matrixToCardMainButton"
|
||||
app:layout_constraintEnd_toEndOf="@id/matrixToCardMainButton"
|
||||
app:layout_constraintStart_toStartOf="@id/matrixToCardMainButton"
|
||||
app:layout_constraintTop_toTopOf="@id/matrixToCardMainButton"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/matrixToCardPeopleYouKnowVisibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="knownMember1,knownMember2,knownMember3,knownMember4,knownMember5,peopleYouMayKnowText"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/matrixToCardContentVisibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="matrixToCardNameText,matrixToCardAvatar,matrixToCardNameText,matrixToCardDescText, matrixToCardMainButton, matrixToCardAliasText, matrixToCardSecondaryButton, matrixToMemberPills,matrixToCardPeopleYouKnowVisibility"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:parentTag="android.widget.FrameLayout">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonStateButtonFlat"
|
||||
style="@style/VectorButtonStyleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
tools:layout_gravity="center_horizontal"
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/buttonStateButtonBig"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:minWidth="120dp"
|
||||
|
|
|
@ -3352,4 +3352,5 @@
|
|||
|
||||
<string name="labs_use_restricted_join_rule">Experimental Space - Restricted Room.</string>
|
||||
<string name="labs_use_restricted_join_rule_desc">Warning requires server support and experimental room version</string>
|
||||
<string name="user_invites_you">%s invites you</string>
|
||||
</resources>
|
||||
|
|
|
@ -152,7 +152,7 @@
|
|||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:background">@null</item>
|
||||
<!--item name="android:textColor">?colorAccent</item-->
|
||||
<item name="android:textColor">?colorAccent</item>
|
||||
<item name="colorControlHighlight">?colorAccent</item>
|
||||
</style>
|
||||
|
||||
|
@ -162,7 +162,7 @@
|
|||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:background">@null</item>
|
||||
<!--item name="android:textColor">?colorAccent</item-->
|
||||
<item name="android:textColor">?colorAccent</item>
|
||||
<item name="colorControlHighlight">?colorAccent</item>
|
||||
<item name="strokeColor">@color/button_background_tint_selector</item>
|
||||
<item name="strokeWidth">1dp</item>
|
||||
|
|
Loading…
Reference in a new issue