Open Space Link initial commit
This commit is contained in:
parent
03ef480bea
commit
ef42591534
@ -24,6 +24,7 @@ sealed class PeekResult {
|
||||
val topic: String?,
|
||||
val avatarUrl: String?,
|
||||
val numJoinedMembers: Int?,
|
||||
val roomType: String?,
|
||||
val viaServers: List<String>
|
||||
) : PeekResult()
|
||||
|
||||
|
@ -25,6 +25,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomTopicContent
|
||||
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsFilter
|
||||
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
|
||||
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
|
||||
@ -100,7 +101,8 @@ internal class DefaultPeekRoomTask @Inject constructor(
|
||||
name = publicRepoResult.name,
|
||||
topic = publicRepoResult.topic,
|
||||
numJoinedMembers = publicRepoResult.numJoinedMembers,
|
||||
viaServers = serverList
|
||||
viaServers = serverList,
|
||||
roomType = null // would be nice to get that from directory...
|
||||
)
|
||||
}
|
||||
|
||||
@ -130,6 +132,10 @@ internal class DefaultPeekRoomTask @Inject constructor(
|
||||
.distinctBy { it.stateKey }
|
||||
.count()
|
||||
|
||||
val roomType = stateEvents
|
||||
.lastOrNull { it.type == EventType.STATE_ROOM_CREATE }
|
||||
?.let { it.content?.toModel<RoomCreateContent>()?.type }
|
||||
|
||||
return PeekResult.Success(
|
||||
roomId = roomId,
|
||||
alias = alias,
|
||||
@ -137,6 +143,7 @@ internal class DefaultPeekRoomTask @Inject constructor(
|
||||
name = name,
|
||||
topic = topic,
|
||||
numJoinedMembers = memberCount,
|
||||
roomType = roomType,
|
||||
viaServers = serverList
|
||||
)
|
||||
} catch (failure: Throwable) {
|
||||
|
@ -72,6 +72,8 @@ import im.vector.app.features.login.LoginSplashFragment
|
||||
import im.vector.app.features.login.LoginWaitForEmailFragment
|
||||
import im.vector.app.features.login.LoginWebFragment
|
||||
import im.vector.app.features.login.terms.LoginTermsFragment
|
||||
import im.vector.app.features.matrixto.MatrixToRoomSpaceFragment
|
||||
import im.vector.app.features.matrixto.MatrixToUserFragment
|
||||
import im.vector.app.features.pin.PinFragment
|
||||
import im.vector.app.features.qrcode.QrCodeScannerFragment
|
||||
import im.vector.app.features.reactions.EmojiChooserFragment
|
||||
@ -654,4 +656,14 @@ interface FragmentModule {
|
||||
@IntoMap
|
||||
@FragmentKey(CreateSpaceDefaultRoomsFragment::class)
|
||||
fun bindCreateSpaceDefaultRoomsFragment(fragment: CreateSpaceDefaultRoomsFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(MatrixToUserFragment::class)
|
||||
fun bindMatrixToUserFragment(fragment: MatrixToUserFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(MatrixToRoomSpaceFragment::class)
|
||||
fun bindMatrixToRoomSpaceFragment(fragment: MatrixToRoomSpaceFragment): Fragment
|
||||
}
|
||||
|
@ -451,6 +451,23 @@ class HomeActivity :
|
||||
return true
|
||||
}
|
||||
|
||||
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean {
|
||||
if (roomId == null) return false
|
||||
val listener = object : MatrixToBottomSheet.InteractionListener {
|
||||
override fun navigateToRoom(roomId: String) {
|
||||
navigator.openRoom(this@HomeActivity, roomId)
|
||||
}
|
||||
|
||||
override fun switchToSpace(spaceId: String) {
|
||||
navigator.switchToSpace(this@HomeActivity, spaceId, null, false)
|
||||
}
|
||||
}
|
||||
|
||||
MatrixToBottomSheet.withLink(deepLink.toString(), listener)
|
||||
.show(supportFragmentManager, "HA#MatrixToBottomSheet")
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newIntent(context: Context, clearNotification: Boolean = false, accountCreation: Boolean = false): Intent {
|
||||
val args = HomeActivityArgs(
|
||||
|
@ -1445,7 +1445,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
override fun onUrlClicked(url: String, title: String): Boolean {
|
||||
permalinkHandler
|
||||
.launch(requireActivity(), url, object : NavigationInterceptor {
|
||||
override fun navToRoom(roomId: String?, eventId: String?): Boolean {
|
||||
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean {
|
||||
// Same room?
|
||||
if (roomId == roomDetailArgs.roomId) {
|
||||
// Navigation to same room
|
||||
@ -1653,7 +1653,7 @@ class RoomDetailFragment @Inject constructor(
|
||||
override fun onRoomCreateLinkClicked(url: String) {
|
||||
permalinkHandler
|
||||
.launch(requireContext(), url, object : NavigationInterceptor {
|
||||
override fun navToRoom(roomId: String?, eventId: String?): Boolean {
|
||||
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean {
|
||||
requireActivity().finish()
|
||||
return false
|
||||
}
|
||||
|
@ -21,4 +21,11 @@ import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
||||
sealed class MatrixToAction : VectorViewModelAction {
|
||||
data class StartChattingWithUser(val matrixItem: MatrixItem) : MatrixToAction()
|
||||
object FailedToResolveUser : MatrixToAction()
|
||||
object FailedToStartChatting : MatrixToAction()
|
||||
data class JoinSpace(val spaceID: String, val viaServers: List<String>?) : MatrixToAction()
|
||||
data class JoinRoom(val roomId: String, val viaServers: List<String>?) : MatrixToAction()
|
||||
data class OpenSpace(val spaceID: String) : MatrixToAction()
|
||||
data class OpenRoom(val roomId: String) : MatrixToAction()
|
||||
// data class OpenSpace(val spaceID: String) : MatrixToAction()
|
||||
}
|
||||
|
@ -21,22 +21,23 @@ import android.os.Parcelable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Loading
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.airbnb.mvrx.Incomplete
|
||||
import com.airbnb.mvrx.MvRx
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
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.extensions.commitTransaction
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.databinding.BottomSheetMatrixToCardBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class MatrixToBottomSheet :
|
||||
VectorBaseBottomSheetDialogFragment<BottomSheetMatrixToCardBinding>() {
|
||||
@ -65,63 +66,41 @@ class MatrixToBottomSheet :
|
||||
|
||||
interface InteractionListener {
|
||||
fun navigateToRoom(roomId: String)
|
||||
fun switchToSpace(spaceId: String) {}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
super.invalidate()
|
||||
when (val item = state.matrixItem) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardContentLoading.isVisible = false
|
||||
views.matrixToCardUserContentVisibility.isVisible = false
|
||||
when (state.linkType) {
|
||||
is PermalinkData.RoomLink -> {
|
||||
views.matrixToCardContentLoading.isVisible = state.roomPeekResult is Incomplete
|
||||
showFragment(MatrixToRoomSpaceFragment::class, Bundle())
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardContentLoading.isVisible = true
|
||||
views.matrixToCardUserContentVisibility.isVisible = false
|
||||
is PermalinkData.UserLink -> {
|
||||
views.matrixToCardContentLoading.isVisible = state.matrixItem is Incomplete
|
||||
showFragment(MatrixToUserFragment::class, Bundle())
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardContentLoading.isVisible = false
|
||||
views.matrixToCardUserContentVisibility.isVisible = true
|
||||
views.matrixToCardNameText.setTextOrHide(item.invoke().displayName)
|
||||
views.matrixToCardUserIdText.setTextOrHide(item.invoke().id)
|
||||
avatarRenderer.render(item.invoke(), views.matrixToCardAvatar)
|
||||
is PermalinkData.GroupLink -> {
|
||||
}
|
||||
is Fail -> {
|
||||
// TODO display some error copy?
|
||||
dismiss()
|
||||
is PermalinkData.FallbackLink -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
when (state.startChattingState) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = false
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = true
|
||||
}
|
||||
is Fail -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = true
|
||||
// TODO display some error copy?
|
||||
dismiss()
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardButtonLoading.isVisible = true
|
||||
views.matrixToCardSendMessageButton.isInvisible = true
|
||||
private fun showFragment(fragmentClass: KClass<out Fragment>, bundle: Bundle) {
|
||||
if (childFragmentManager.findFragmentByTag(fragmentClass.simpleName) == null) {
|
||||
childFragmentManager.commitTransaction {
|
||||
replace(views.matrixToCardFragmentContainer.id,
|
||||
fragmentClass.java,
|
||||
bundle,
|
||||
fragmentClass.simpleName
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
views.matrixToCardSendMessageButton.debouncedClicks {
|
||||
withState(viewModel) {
|
||||
it.matrixItem.invoke()?.let { item ->
|
||||
viewModel.handle(MatrixToAction.StartChattingWithUser(item))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.observeViewEvents {
|
||||
when (it) {
|
||||
@ -130,6 +109,16 @@ class MatrixToBottomSheet :
|
||||
dismiss()
|
||||
}
|
||||
MatrixToViewEvents.Dismiss -> dismiss()
|
||||
is MatrixToViewEvents.NavigateToSpace -> {
|
||||
interactionListener?.switchToSpace(it.spaceId)
|
||||
dismiss()
|
||||
}
|
||||
is MatrixToViewEvents.ShowModalError -> {
|
||||
AlertDialog.Builder(requireContext())
|
||||
.setMessage(it.error)
|
||||
.setPositiveButton(getString(R.string.ok), null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,15 +19,45 @@ package im.vector.app.features.matrixto
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
||||
data class MatrixToBottomSheetState(
|
||||
val deepLink: String,
|
||||
val linkType: PermalinkData,
|
||||
val matrixItem: Async<MatrixItem> = Uninitialized,
|
||||
val startChattingState: Async<Unit> = Uninitialized
|
||||
val startChattingState: Async<Unit> = Uninitialized,
|
||||
val roomPeekResult: Async<RoomInfoResult> = Uninitialized
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: MatrixToBottomSheet.MatrixToArgs) : this(
|
||||
deepLink = args.matrixToLink
|
||||
deepLink = args.matrixToLink,
|
||||
linkType = PermalinkParser.parse(args.matrixToLink)
|
||||
)
|
||||
}
|
||||
|
||||
sealed class RoomInfoResult {
|
||||
data class FullInfo(
|
||||
val roomItem: MatrixItem.RoomItem,
|
||||
val name: String,
|
||||
val topic: String,
|
||||
val memberCount: Int?,
|
||||
val alias: String?,
|
||||
val membership: Membership,
|
||||
val roomType: String?,
|
||||
val viaServers: List<String>?
|
||||
) : RoomInfoResult()
|
||||
|
||||
data class PartialInfo(
|
||||
val roomId: String?,
|
||||
val viaServers: List<String>
|
||||
) : RoomInfoResult()
|
||||
|
||||
data class UnknownAlias(
|
||||
val alias: String?
|
||||
) : RoomInfoResult()
|
||||
|
||||
object NotFound : RoomInfoResult()
|
||||
}
|
||||
|
@ -25,9 +25,10 @@ import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
import im.vector.app.core.platform.VectorViewModel
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
@ -35,19 +36,26 @@ import im.vector.app.features.createdirect.DirectRoomHelper
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.matrix.android.sdk.api.extensions.tryOrNull
|
||||
import org.matrix.android.sdk.api.raw.RawService
|
||||
import org.matrix.android.sdk.api.session.Session
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkData
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkParser
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
|
||||
import org.matrix.android.sdk.api.session.space.SpaceService
|
||||
import org.matrix.android.sdk.api.session.user.model.User
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
|
||||
import org.matrix.android.sdk.internal.util.awaitCallback
|
||||
import timber.log.Timber
|
||||
|
||||
class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
@Assisted initialState: MatrixToBottomSheetState,
|
||||
private val session: Session,
|
||||
private val stringProvider: StringProvider,
|
||||
private val directRoomHelper: DirectRoomHelper,
|
||||
private val rawService: RawService) : VectorViewModel<MatrixToBottomSheetState, MatrixToAction, MatrixToViewEvents>(initialState) {
|
||||
private val errorFormatter: ErrorFormatter)
|
||||
: VectorViewModel<MatrixToBottomSheetState, MatrixToAction, MatrixToViewEvents>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory {
|
||||
@ -55,8 +63,23 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
init {
|
||||
setState {
|
||||
copy(matrixItem = Loading())
|
||||
when (initialState.linkType) {
|
||||
is PermalinkData.RoomLink -> {
|
||||
setState {
|
||||
copy(roomPeekResult = Loading())
|
||||
}
|
||||
}
|
||||
is PermalinkData.UserLink -> {
|
||||
setState {
|
||||
copy(matrixItem = Loading())
|
||||
}
|
||||
}
|
||||
is PermalinkData.GroupLink -> {
|
||||
// Not yet supported
|
||||
}
|
||||
is PermalinkData.FallbackLink -> {
|
||||
// Not yet supported
|
||||
}
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
resolveLink(initialState)
|
||||
@ -64,7 +87,7 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
}
|
||||
|
||||
private suspend fun resolveLink(initialState: MatrixToBottomSheetState) {
|
||||
val permalinkData = PermalinkParser.parse(initialState.deepLink)
|
||||
val permalinkData = initialState.linkType
|
||||
if (permalinkData is PermalinkData.FallbackLink) {
|
||||
setState {
|
||||
copy(
|
||||
@ -75,8 +98,8 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
when (permalinkData) {
|
||||
is PermalinkData.UserLink -> {
|
||||
when (permalinkData) {
|
||||
is PermalinkData.UserLink -> {
|
||||
val user = resolveUser(permalinkData.userId)
|
||||
setState {
|
||||
copy(
|
||||
@ -85,11 +108,79 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
is PermalinkData.RoomLink -> {
|
||||
// not yet supported
|
||||
_viewEvents.post(MatrixToViewEvents.Dismiss)
|
||||
is PermalinkData.RoomLink -> {
|
||||
// could this room be already known
|
||||
val knownRoom = if (permalinkData.isRoomAlias) {
|
||||
tryOrNull {
|
||||
awaitCallback<Optional<RoomAliasDescription>> {
|
||||
session.getRoomIdByAlias(permalinkData.roomIdOrAlias, false, it)
|
||||
}
|
||||
}
|
||||
?.getOrNull()
|
||||
?.roomId?.let {
|
||||
session.getRoom(permalinkData.roomIdOrAlias)
|
||||
}
|
||||
} else {
|
||||
session.getRoom(permalinkData.roomIdOrAlias)
|
||||
}?.roomSummary()
|
||||
|
||||
if (knownRoom != null) {
|
||||
setState {
|
||||
copy(
|
||||
roomPeekResult = Success(
|
||||
RoomInfoResult.FullInfo(
|
||||
roomItem = knownRoom.toMatrixItem(),
|
||||
name = knownRoom.name,
|
||||
topic = knownRoom.topic,
|
||||
memberCount = knownRoom.joinedMembersCount,
|
||||
alias = knownRoom.canonicalAlias,
|
||||
membership = knownRoom.membership,
|
||||
roomType = knownRoom.roomType,
|
||||
viaServers = null
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
||||
val result = when (val peekResult = tryOrNull { resolveRoom(permalinkData.roomIdOrAlias) }) {
|
||||
is PeekResult.Success -> {
|
||||
RoomInfoResult.FullInfo(
|
||||
roomItem = MatrixItem.RoomItem(peekResult.roomId, peekResult.name, peekResult.avatarUrl),
|
||||
name = peekResult.name ?: "",
|
||||
topic = peekResult.topic ?: "",
|
||||
memberCount = peekResult.numJoinedMembers,
|
||||
alias = peekResult.alias,
|
||||
membership = Membership.NONE,
|
||||
roomType = peekResult.roomType,
|
||||
viaServers = peekResult.viaServers.takeIf { it.isNotEmpty() } ?: permalinkData.viaParameters
|
||||
)
|
||||
}
|
||||
is PeekResult.PeekingNotAllowed -> {
|
||||
RoomInfoResult.PartialInfo(
|
||||
roomId = permalinkData.roomIdOrAlias,
|
||||
viaServers = permalinkData.viaParameters
|
||||
)
|
||||
}
|
||||
PeekResult.UnknownAlias -> {
|
||||
RoomInfoResult.NotFound
|
||||
}
|
||||
null -> {
|
||||
RoomInfoResult.PartialInfo(
|
||||
roomId = permalinkData.roomIdOrAlias,
|
||||
viaServers = permalinkData.viaParameters
|
||||
).takeIf { permalinkData.isRoomAlias.not() }
|
||||
?: RoomInfoResult.NotFound
|
||||
}
|
||||
}
|
||||
setState {
|
||||
copy(
|
||||
roomPeekResult = Success(result)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
is PermalinkData.GroupLink -> {
|
||||
is PermalinkData.GroupLink -> {
|
||||
// not yet supported
|
||||
_viewEvents.post(MatrixToViewEvents.Dismiss)
|
||||
}
|
||||
@ -105,6 +196,19 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
?: User(userId, null, null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Let's try to get some information about that room,
|
||||
* main thing is trying to see if it's a space or a room
|
||||
*/
|
||||
private suspend fun resolveRoom(roomIdOrAlias: String): PeekResult {
|
||||
return tryOrNull { // this should not throw as it returns a result, but better be safe
|
||||
awaitCallback {
|
||||
session.peekRoom(roomIdOrAlias, it)
|
||||
}
|
||||
}
|
||||
?: PeekResult.PeekingNotAllowed(roomIdOrAlias, null, emptyList())
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<MatrixToBottomSheetViewModel, MatrixToBottomSheetState> {
|
||||
override fun create(viewModelContext: ViewModelContext, state: MatrixToBottomSheetState): MatrixToBottomSheetViewModel? {
|
||||
val fragment: MatrixToBottomSheet = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
@ -116,14 +220,75 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor(
|
||||
override fun handle(action: MatrixToAction) {
|
||||
when (action) {
|
||||
is MatrixToAction.StartChattingWithUser -> handleStartChatting(action)
|
||||
MatrixToAction.FailedToResolveUser -> {
|
||||
_viewEvents.post(MatrixToViewEvents.Dismiss)
|
||||
}
|
||||
MatrixToAction.FailedToStartChatting -> {
|
||||
_viewEvents.post(MatrixToViewEvents.Dismiss)
|
||||
}
|
||||
is MatrixToAction.JoinSpace -> handleJoinSpace(action)
|
||||
is MatrixToAction.JoinRoom -> handleJoinRoom(action)
|
||||
is MatrixToAction.OpenSpace -> {
|
||||
_viewEvents.post(MatrixToViewEvents.NavigateToSpace(action.spaceID))
|
||||
}
|
||||
is MatrixToAction.OpenRoom -> {
|
||||
_viewEvents.post(MatrixToViewEvents.NavigateToRoom(action.roomId))
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun handleStartChatting(action: MatrixToAction.StartChattingWithUser) {
|
||||
private fun handleJoinSpace(joinSpace: MatrixToAction.JoinSpace) {
|
||||
setState {
|
||||
copy(startChattingState = Loading())
|
||||
}
|
||||
viewModelScope.launch {
|
||||
setState {
|
||||
copy(startChattingState = Loading())
|
||||
try {
|
||||
val joinResult = session.spaceService().joinSpace(joinSpace.spaceID, null, joinSpace.viaServers?.take(3) ?: emptyList())
|
||||
if (joinResult.isSuccess()) {
|
||||
_viewEvents.post(MatrixToViewEvents.NavigateToSpace(joinSpace.spaceID))
|
||||
} else {
|
||||
val errMsg = errorFormatter.toHumanReadable((joinResult as? SpaceService.JoinSpaceResult.Fail)?.error)
|
||||
_viewEvents.post(MatrixToViewEvents.ShowModalError(errMsg))
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
_viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure)))
|
||||
} finally {
|
||||
setState {
|
||||
// we can hide this button has we will navigate out
|
||||
copy(startChattingState = Uninitialized)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleJoinRoom(action: MatrixToAction.JoinRoom) {
|
||||
setState {
|
||||
copy(startChattingState = Loading())
|
||||
}
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
awaitCallback<Unit> {
|
||||
session.joinRoom(action.roomId, null, action.viaServers?.take(3) ?: emptyList(), it)
|
||||
}
|
||||
_viewEvents.post(MatrixToViewEvents.NavigateToRoom(action.roomId))
|
||||
} catch (failure: Throwable) {
|
||||
_viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure)))
|
||||
} finally {
|
||||
setState {
|
||||
// we can hide this button has we will navigate out
|
||||
copy(startChattingState = Uninitialized)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleStartChatting(action: MatrixToAction.StartChattingWithUser) {
|
||||
setState {
|
||||
copy(startChattingState = Loading())
|
||||
}
|
||||
viewModelScope.launch {
|
||||
val roomId = try {
|
||||
directRoomHelper.ensureDMExists(action.matrixItem.id)
|
||||
} catch (failure: Throwable) {
|
||||
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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.matrixto
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isInvisible
|
||||
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.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentMatrixToRoomSpaceCardBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import org.matrix.android.sdk.api.session.room.model.Membership
|
||||
import org.matrix.android.sdk.api.session.room.model.RoomType
|
||||
import javax.inject.Inject
|
||||
|
||||
class MatrixToRoomSpaceFragment @Inject constructor(
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment<FragmentMatrixToRoomSpaceCardBinding>() {
|
||||
|
||||
private val sharedViewModel: MatrixToBottomSheetViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMatrixToRoomSpaceCardBinding {
|
||||
return FragmentMatrixToRoomSpaceCardBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
views.matrixToCardMainButton.debouncedClicks {
|
||||
mainButtonClicked()
|
||||
}
|
||||
views.matrixToCardSecondaryButton.debouncedClicks {
|
||||
secondaryButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
when (val item = state.roomPeekResult) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardContentVisibility.isVisible = false
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardContentVisibility.isVisible = false
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardContentVisibility.isVisible = true
|
||||
when (val peek = item.invoke()) {
|
||||
is RoomInfoResult.FullInfo -> {
|
||||
val matrixItem = peek.roomItem
|
||||
if (peek.roomType == RoomType.SPACE) {
|
||||
avatarRenderer.renderSpace(matrixItem, views.matrixToCardAvatar)
|
||||
} else {
|
||||
avatarRenderer.render(matrixItem, views.matrixToCardAvatar)
|
||||
}
|
||||
views.matrixToCardNameText.setTextOrHide(peek.name)
|
||||
views.matrixToCardAliasText.setTextOrHide(peek.alias)
|
||||
views.matrixToCardDescText.setTextOrHide(peek.topic)
|
||||
val memberCount = peek.memberCount
|
||||
if (memberCount != null) {
|
||||
views.matrixToMemberPills.isVisible = true
|
||||
views.spaceChildMemberCountText.text = resources.getQuantityString(R.plurals.room_title_members, memberCount, memberCount)
|
||||
} else {
|
||||
// hide the pill
|
||||
views.matrixToMemberPills.isVisible = false
|
||||
}
|
||||
|
||||
when (peek.membership) {
|
||||
Membership.LEAVE,
|
||||
Membership.NONE -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardMainButton.text = getString(R.string.join_space)
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
Membership.INVITE -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardSecondaryButton.isVisible = true
|
||||
views.matrixToCardMainButton.text = getString(R.string.join_space)
|
||||
views.matrixToCardSecondaryButton.text = getString(R.string.decline)
|
||||
}
|
||||
Membership.JOIN -> {
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
views.matrixToCardMainButton.text = getString(R.string.action_open)
|
||||
}
|
||||
Membership.KNOCK,
|
||||
Membership.BAN -> {
|
||||
// What to do here ?
|
||||
views.matrixToCardMainButton.isVisible = false
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
is RoomInfoResult.PartialInfo -> {
|
||||
// It may still be possible to join
|
||||
views.matrixToCardNameText.text = peek.roomId
|
||||
views.matrixToCardAliasText.isVisible = false
|
||||
views.matrixToMemberPills.isVisible = false
|
||||
views.matrixToCardDescText.setTextOrHide(getString(R.string.room_preview_no_preview))
|
||||
|
||||
views.matrixToCardMainButton.text = getString(R.string.join_anyway)
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
RoomInfoResult.NotFound -> {
|
||||
// we cannot join :/
|
||||
views.matrixToCardNameText.isVisible = false
|
||||
views.matrixToCardAliasText.isVisible = false
|
||||
views.matrixToMemberPills.isVisible = false
|
||||
views.matrixToCardDescText.setTextOrHide(getString(R.string.room_preview_not_found))
|
||||
|
||||
views.matrixToCardMainButton.isVisible = false
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
is RoomInfoResult.UnknownAlias -> {
|
||||
views.matrixToCardNameText.isVisible = false
|
||||
views.matrixToCardAliasText.isVisible = false
|
||||
views.spaceChildMemberCountText.isVisible = false
|
||||
views.matrixToCardDescText.setTextOrHide(getString(R.string.room_alias_preview_not_found))
|
||||
|
||||
views.matrixToCardMainButton.isVisible = false
|
||||
views.matrixToCardSecondaryButton.isVisible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
is Fail -> {
|
||||
// TODO display some error copy?
|
||||
sharedViewModel.handle(MatrixToAction.FailedToResolveUser)
|
||||
}
|
||||
}
|
||||
|
||||
when (state.startChattingState) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
// views.matrixToCardMainButton.isVisible = false
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
}
|
||||
is Fail -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardMainButton.isVisible = true
|
||||
// TODO display some error copy?
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardButtonLoading.isVisible = true
|
||||
views.matrixToCardMainButton.isInvisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun mainButtonClicked() = withState(sharedViewModel) { state ->
|
||||
when (val info = state.roomPeekResult.invoke()) {
|
||||
is RoomInfoResult.FullInfo -> {
|
||||
when (info.membership) {
|
||||
Membership.NONE,
|
||||
Membership.INVITE,
|
||||
Membership.LEAVE -> {
|
||||
if (info.roomType == RoomType.SPACE) {
|
||||
sharedViewModel.handle(MatrixToAction.JoinSpace(info.roomItem.id, info.viaServers))
|
||||
} else {
|
||||
sharedViewModel.handle(MatrixToAction.JoinRoom(info.roomItem.id, info.viaServers))
|
||||
}
|
||||
}
|
||||
Membership.JOIN -> {
|
||||
if (info.roomType == RoomType.SPACE) {
|
||||
sharedViewModel.handle(MatrixToAction.OpenSpace(info.roomItem.id))
|
||||
} else {
|
||||
sharedViewModel.handle(MatrixToAction.OpenRoom(info.roomItem.id))
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
is RoomInfoResult.PartialInfo -> {
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun secondaryButtonClicked() = withState(sharedViewModel) { state ->
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.matrixto
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isInvisible
|
||||
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.parentFragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.VectorBaseFragment
|
||||
import im.vector.app.databinding.FragmentMatrixToUserCardBinding
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
class MatrixToUserFragment @Inject constructor(
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment<FragmentMatrixToUserCardBinding>() {
|
||||
|
||||
private val sharedViewModel: MatrixToBottomSheetViewModel by parentFragmentViewModel()
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentMatrixToUserCardBinding {
|
||||
return FragmentMatrixToUserCardBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
views.matrixToCardSendMessageButton.debouncedClicks {
|
||||
withState(sharedViewModel) {
|
||||
it.matrixItem.invoke()?.let { item ->
|
||||
sharedViewModel.handle(MatrixToAction.StartChattingWithUser(item))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(sharedViewModel) { state ->
|
||||
when (val item = state.matrixItem) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardUserContentVisibility.isVisible = false
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardUserContentVisibility.isVisible = false
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardUserContentVisibility.isVisible = true
|
||||
views.matrixToCardNameText.setTextOrHide(item.invoke().displayName)
|
||||
views.matrixToCardUserIdText.setTextOrHide(item.invoke().id)
|
||||
avatarRenderer.render(item.invoke(), views.matrixToCardAvatar)
|
||||
}
|
||||
is Fail -> {
|
||||
// TODO display some error copy?
|
||||
sharedViewModel.handle(MatrixToAction.FailedToResolveUser)
|
||||
}
|
||||
}
|
||||
|
||||
when (state.startChattingState) {
|
||||
Uninitialized -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = false
|
||||
}
|
||||
is Success -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = true
|
||||
}
|
||||
is Fail -> {
|
||||
views.matrixToCardButtonLoading.isVisible = false
|
||||
views.matrixToCardSendMessageButton.isVisible = true
|
||||
// TODO display some error copy?
|
||||
sharedViewModel.handle(MatrixToAction.FailedToStartChatting)
|
||||
}
|
||||
is Loading -> {
|
||||
views.matrixToCardButtonLoading.isVisible = true
|
||||
views.matrixToCardSendMessageButton.isInvisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,5 +20,7 @@ import im.vector.app.core.platform.VectorViewEvents
|
||||
|
||||
sealed class MatrixToViewEvents : VectorViewEvents {
|
||||
data class NavigateToRoom(val roomId: String) : MatrixToViewEvents()
|
||||
data class NavigateToSpace(val spaceId: String) : MatrixToViewEvents()
|
||||
data class ShowModalError(val error: String) : MatrixToViewEvents()
|
||||
object Dismiss : MatrixToViewEvents()
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
||||
buildTask: Boolean
|
||||
): Single<Boolean> {
|
||||
return when (permalinkData) {
|
||||
is PermalinkData.RoomLink -> {
|
||||
is PermalinkData.RoomLink -> {
|
||||
permalinkData.getRoomId()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map {
|
||||
val roomId = it.getOrNull()
|
||||
if (navigationInterceptor?.navToRoom(roomId, permalinkData.eventId) != true) {
|
||||
if (navigationInterceptor?.navToRoom(roomId, permalinkData.eventId, rawLink) != true) {
|
||||
openRoom(
|
||||
context = context,
|
||||
roomId = roomId,
|
||||
@ -94,11 +94,11 @@ class PermalinkHandler @Inject constructor(private val activeSessionHolder: Acti
|
||||
true
|
||||
}
|
||||
}
|
||||
is PermalinkData.GroupLink -> {
|
||||
is PermalinkData.GroupLink -> {
|
||||
navigator.openGroupDetail(permalinkData.groupId, context, buildTask)
|
||||
Single.just(true)
|
||||
}
|
||||
is PermalinkData.UserLink -> {
|
||||
is PermalinkData.UserLink -> {
|
||||
if (navigationInterceptor?.navToMemberProfile(permalinkData.userId, rawLink) != true) {
|
||||
navigator.openRoomMemberProfile(userId = permalinkData.userId, roomId = null, context = context, buildTask = buildTask)
|
||||
}
|
||||
@ -196,7 +196,7 @@ interface NavigationInterceptor {
|
||||
/**
|
||||
* Return true if the navigation has been intercepted
|
||||
*/
|
||||
fun navToRoom(roomId: String?, eventId: String? = null): Boolean {
|
||||
fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri? = null): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.app.features.roomdirectory
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
@ -127,7 +128,7 @@ class PublicRoomsFragment @Inject constructor(
|
||||
val permalink = session.permalinkService().createPermalink(roomIdOrAlias)
|
||||
permalinkHandler
|
||||
.launch(requireContext(), permalink, object : NavigationInterceptor {
|
||||
override fun navToRoom(roomId: String?, eventId: String?): Boolean {
|
||||
override fun navToRoom(roomId: String?, eventId: String?, deepLink: Uri?): Boolean {
|
||||
requireActivity().finish()
|
||||
return false
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@ -10,88 +9,13 @@
|
||||
android:id="@+id/matrixToCardContentLoading"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<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_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardNameText"
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/matrixToCardFragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/matrixToCardAvatar"
|
||||
tools:text="@sample/matrix.json/data/displayName" />
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardUserIdText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardNameText"
|
||||
tools:text="@sample/matrix.json/data/mxid" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/matrixToCardSendMessageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
android:minWidth="130dp"
|
||||
android:text="@string/start_chatting"
|
||||
app:icon="@drawable/ic_fab_add_chat"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardUserIdText" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/matrixToCardButtonLoading"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintEnd_toEndOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintStart_toStartOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintTop_toTopOf="@id/matrixToCardSendMessageButton"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/matrixToCardUserContentVisibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="matrixToCardAvatar,matrixToCardNameText,matrixToCardUserIdText"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</RelativeLayout>
|
||||
|
@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<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_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardNameText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
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="center"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardNameText"
|
||||
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_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardAliasText">
|
||||
|
||||
<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" />
|
||||
|
||||
<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>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardDescText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:maxLines="4"
|
||||
android:textAlignment="center"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToMemberPills"
|
||||
tools:text="@sample/matrix.json/data/roomTopic" />
|
||||
|
||||
<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/matrixToCardDescText"
|
||||
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" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/matrixToCardButtonLoading"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
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/matrixToCardContentVisibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="matrixToCardNameText,matrixToCardAvatar,matrixToCardNameText,matrixToCardDescText, matrixToCardMainButton, matrixToCardAliasText, matrixToCardSecondaryButton, matrixToMemberPills"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
86
vector/src/main/res/layout/fragment_matrix_to_user_card.xml
Normal file
86
vector/src/main/res/layout/fragment_matrix_to_user_card.xml
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<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_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardNameText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin_big"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/matrixToCardAvatar"
|
||||
tools:text="@sample/matrix.json/data/displayName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixToCardUserIdText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textAlignment="center"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardNameText"
|
||||
tools:text="@sample/matrix.json/data/mxid" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/matrixToCardSendMessageButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="@dimen/layout_vertical_margin_big"
|
||||
android:minWidth="130dp"
|
||||
android:text="@string/start_chatting"
|
||||
app:icon="@drawable/ic_fab_add_chat"
|
||||
app:iconTint="@color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixToCardUserIdText" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/matrixToCardButtonLoading"
|
||||
style="?android:attr/progressBarStyleSmall"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintEnd_toEndOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintStart_toStartOf="@id/matrixToCardSendMessageButton"
|
||||
app:layout_constraintTop_toTopOf="@id/matrixToCardSendMessageButton"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/matrixToCardUserContentVisibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="matrixToCardAvatar,matrixToCardNameText,matrixToCardUserIdText"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -3286,6 +3286,9 @@
|
||||
<!-- First one is the space name, and the second one is the matrix.to link -->
|
||||
<string name="share_space_link_message">Join my space %1$s %2$s</string>
|
||||
<string name="skip_for_now">Skip for now</string>
|
||||
<string name="join_space">Join Space</string>
|
||||
<string name="join_anyway">Join Anyway</string>
|
||||
<string name="room_alias_preview_not_found">This alias is not accessible at this time.\nTry again later, or ask a room admin to check if you have access.</string>
|
||||
|
||||
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user