Merge pull request #3259 from vector-im/feature/bca/spaces_advertise_beta

Invite bottom sheet + fixes + beta tag
This commit is contained in:
Benoit Marty 2021-05-05 16:26:54 +02:00 committed by GitHub
commit b09e509db7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 808 additions and 230 deletions

View file

@ -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()
}

View file

@ -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

View file

@ -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(

View file

@ -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()
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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()
}

View file

@ -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 ->

View file

@ -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))
}
}
}
}

View file

@ -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()
}

View file

@ -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()
}

View file

@ -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
)
}

View file

@ -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)))
}
}
}
}
}
}

View file

@ -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")

View file

@ -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)

View file

@ -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)
}

View file

@ -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()
}

View file

@ -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))
}
}
}

View 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>

View file

@ -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>

View file

@ -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"

View file

@ -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>

View file

@ -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>