mirror of
https://github.com/element-hq/element-android
synced 2024-11-24 18:35:40 +03:00
Join room from room preview
This commit is contained in:
parent
33fbcc8ba3
commit
6244913ab9
14 changed files with 277 additions and 32 deletions
|
@ -28,9 +28,10 @@ class ErrorFormatter(val stringProvider: StringProvider) {
|
||||||
return failure.localizedMessage
|
return failure.localizedMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toHumanReadable(throwable: Throwable): String {
|
fun toHumanReadable(throwable: Throwable?): String {
|
||||||
|
|
||||||
return when (throwable) {
|
return when (throwable) {
|
||||||
|
null -> ""
|
||||||
is Failure.NetworkConnection -> stringProvider.getString(R.string.error_no_network)
|
is Failure.NetworkConnection -> stringProvider.getString(R.string.error_no_network)
|
||||||
else -> throwable.localizedMessage
|
else -> throwable.localizedMessage
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.core.view.isInvisible
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
|
@ -43,14 +44,13 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||||
fun onRetryClicked()
|
fun onRetryClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Big or Flat button
|
||||||
|
var button: Button
|
||||||
|
|
||||||
init {
|
init {
|
||||||
View.inflate(context, R.layout.view_button_state, this)
|
View.inflate(context, R.layout.view_button_state, this)
|
||||||
layoutParams = LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
layoutParams = LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
|
|
||||||
buttonStateButton.setOnClickListener {
|
|
||||||
callback?.onButtonClicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
buttonStateRetry.setOnClickListener {
|
buttonStateRetry.setOnClickListener {
|
||||||
callback?.onRetryClicked()
|
callback?.onRetryClicked()
|
||||||
}
|
}
|
||||||
|
@ -62,20 +62,32 @@ class ButtonStateView @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||||
0, 0)
|
0, 0)
|
||||||
.apply {
|
.apply {
|
||||||
try {
|
try {
|
||||||
buttonStateButton.text = getString(R.styleable.ButtonStateView_bsv_button_text)
|
if (getBoolean(R.styleable.ButtonStateView_bsv_use_flat_button, true)) {
|
||||||
|
button = buttonStateButtonFlat
|
||||||
|
buttonStateButtonBig.isVisible = false
|
||||||
|
} else {
|
||||||
|
button = buttonStateButtonBig
|
||||||
|
buttonStateButtonFlat.isVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
button.text = getString(R.styleable.ButtonStateView_bsv_button_text)
|
||||||
buttonStateLoaded.setImageDrawable(getDrawable(R.styleable.ButtonStateView_bsv_loaded_image_src))
|
buttonStateLoaded.setImageDrawable(getDrawable(R.styleable.ButtonStateView_bsv_loaded_image_src))
|
||||||
} finally {
|
} finally {
|
||||||
recycle()
|
recycle()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.setOnClickListener {
|
||||||
|
callback?.onButtonClicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun render(newState: State) {
|
fun render(newState: State) {
|
||||||
if (newState == State.Button) {
|
if (newState == State.Button) {
|
||||||
buttonStateButton.isVisible = true
|
button.isVisible = true
|
||||||
} else {
|
} else {
|
||||||
// We use isInvisible because we want to keep button space in the layout
|
// We use isInvisible because we want to keep button space in the layout
|
||||||
buttonStateButton.isInvisible = true
|
button.isInvisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
buttonStateLoading.isVisible = newState == State.Loading
|
buttonStateLoading.isVisible = newState == State.Loading
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 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.riotredesign.features.roomdirectory
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join state of a room
|
||||||
|
*/
|
||||||
|
enum class JoinState {
|
||||||
|
NOT_JOINED,
|
||||||
|
JOINING,
|
||||||
|
JOINING_ERROR,
|
||||||
|
// Room is joined and this is confirmed by the sync
|
||||||
|
JOINED
|
||||||
|
}
|
|
@ -30,13 +30,6 @@ import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
@EpoxyModelClass(layout = R.layout.item_public_room)
|
@EpoxyModelClass(layout = R.layout.item_public_room)
|
||||||
abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
|
abstract class PublicRoomItem : VectorEpoxyModel<PublicRoomItem.Holder>() {
|
||||||
|
|
||||||
enum class JoinState {
|
|
||||||
NOT_JOINED,
|
|
||||||
JOINING,
|
|
||||||
JOINING_ERROR,
|
|
||||||
JOINED
|
|
||||||
}
|
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var avatarUrl: String? = null
|
var avatarUrl: String? = null
|
||||||
|
|
||||||
|
|
|
@ -85,10 +85,10 @@ class PublicRoomsController(private val stringProvider: StringProvider,
|
||||||
nbOfMembers(publicRoom.numJoinedMembers)
|
nbOfMembers(publicRoom.numJoinedMembers)
|
||||||
|
|
||||||
val joinState = when {
|
val joinState = when {
|
||||||
viewState.joinedRoomsIds.contains(publicRoom.roomId) -> PublicRoomItem.JoinState.JOINED
|
viewState.joinedRoomsIds.contains(publicRoom.roomId) -> JoinState.JOINED
|
||||||
viewState.joiningRoomsIds.contains(publicRoom.roomId) -> PublicRoomItem.JoinState.JOINING
|
viewState.joiningRoomsIds.contains(publicRoom.roomId) -> JoinState.JOINING
|
||||||
viewState.joiningErrorRoomsIds.contains(publicRoom.roomId) -> PublicRoomItem.JoinState.JOINING_ERROR
|
viewState.joiningErrorRoomsIds.contains(publicRoom.roomId) -> JoinState.JOINING_ERROR
|
||||||
else -> PublicRoomItem.JoinState.NOT_JOINED
|
else -> JoinState.NOT_JOINED
|
||||||
}
|
}
|
||||||
|
|
||||||
joinState(joinState)
|
joinState(joinState)
|
||||||
|
@ -103,7 +103,7 @@ class PublicRoomsController(private val stringProvider: StringProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: PublicRoomItem.JoinState)
|
fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: JoinState)
|
||||||
fun onPublicRoomJoin(publicRoom: PublicRoom)
|
fun onPublicRoomJoin(publicRoom: PublicRoom)
|
||||||
fun loadMore()
|
fun loadMore()
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,21 +117,21 @@ class PublicRoomsFragment : VectorBaseFragment(), PublicRoomsController.Callback
|
||||||
publicRoomsList.setController(publicRoomsController)
|
publicRoomsList.setController(publicRoomsController)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: PublicRoomItem.JoinState) {
|
override fun onPublicRoomClicked(publicRoom: PublicRoom, joinState: JoinState) {
|
||||||
Timber.v("PublicRoomClicked: $publicRoom")
|
Timber.v("PublicRoomClicked: $publicRoom")
|
||||||
|
|
||||||
when (joinState) {
|
when (joinState) {
|
||||||
PublicRoomItem.JoinState.JOINED -> {
|
JoinState.JOINED -> {
|
||||||
val args = RoomDetailArgs(publicRoom.roomId)
|
val args = RoomDetailArgs(publicRoom.roomId)
|
||||||
val roomDetailIntent = RoomDetailActivity.newIntent(requireActivity(), args)
|
val roomDetailIntent = RoomDetailActivity.newIntent(requireActivity(), args)
|
||||||
requireActivity().startActivity(roomDetailIntent)
|
requireActivity().startActivity(roomDetailIntent)
|
||||||
}
|
}
|
||||||
PublicRoomItem.JoinState.NOT_JOINED,
|
JoinState.NOT_JOINED,
|
||||||
PublicRoomItem.JoinState.JOINING_ERROR -> {
|
JoinState.JOINING_ERROR -> {
|
||||||
// ROOM PREVIEW
|
// ROOM PREVIEW
|
||||||
requireActivity().startActivity(RoomPreviewActivity.getIntent(requireActivity(), publicRoom))
|
requireActivity().startActivity(RoomPreviewActivity.getIntent(requireActivity(), publicRoom))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Snackbar.make(publicRoomsCoordinator, getString(R.string.please_wait), Snackbar.LENGTH_SHORT)
|
Snackbar.make(publicRoomsCoordinator, getString(R.string.please_wait), Snackbar.LENGTH_SHORT)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,13 +19,20 @@ package im.vector.riotredesign.features.roomdirectory.roompreview
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.transition.TransitionManager
|
||||||
import com.airbnb.mvrx.args
|
import com.airbnb.mvrx.args
|
||||||
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
|
import com.airbnb.mvrx.withState
|
||||||
import im.vector.riotredesign.R
|
import im.vector.riotredesign.R
|
||||||
|
import im.vector.riotredesign.core.error.ErrorFormatter
|
||||||
import im.vector.riotredesign.core.extensions.setTextOrHide
|
import im.vector.riotredesign.core.extensions.setTextOrHide
|
||||||
|
import im.vector.riotredesign.core.platform.ButtonStateView
|
||||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotredesign.features.home.AvatarRenderer
|
import im.vector.riotredesign.features.home.AvatarRenderer
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.JoinState
|
||||||
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryModule
|
import im.vector.riotredesign.features.roomdirectory.RoomDirectoryModule
|
||||||
import kotlinx.android.synthetic.main.fragment_room_preview_no_preview.*
|
import kotlinx.android.synthetic.main.fragment_room_preview_no_preview.*
|
||||||
|
import org.koin.android.ext.android.get
|
||||||
import org.koin.android.scope.ext.android.bindScope
|
import org.koin.android.scope.ext.android.bindScope
|
||||||
import org.koin.android.scope.ext.android.getOrCreateScope
|
import org.koin.android.scope.ext.android.getOrCreateScope
|
||||||
|
|
||||||
|
@ -37,12 +44,17 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val errorFormatter = get<ErrorFormatter>()
|
||||||
|
private val roomPreviewViewModel: RoomPreviewViewModel by fragmentViewModel()
|
||||||
|
|
||||||
private val roomPreviewData: RoomPreviewData by args()
|
private val roomPreviewData: RoomPreviewData by args()
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
bindScope(getOrCreateScope(RoomDirectoryModule.ROOM_DIRECTORY_SCOPE))
|
bindScope(getOrCreateScope(RoomDirectoryModule.ROOM_DIRECTORY_SCOPE))
|
||||||
setupToolbar(roomPreviewNoPreviewToolbar)
|
setupToolbar(roomPreviewNoPreviewToolbar)
|
||||||
|
|
||||||
|
roomPreviewViewModel.init(roomPreviewData.roomId)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getLayoutResId() = R.layout.fragment_room_preview_no_preview
|
override fun getLayoutResId() = R.layout.fragment_room_preview_no_preview
|
||||||
|
@ -54,8 +66,35 @@ class RoomPreviewNoPreviewFragment : VectorBaseFragment() {
|
||||||
roomPreviewNoPreviewName.text = roomPreviewData.roomName
|
roomPreviewNoPreviewName.text = roomPreviewData.roomName
|
||||||
roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic)
|
roomPreviewNoPreviewTopic.setTextOrHide(roomPreviewData.topic)
|
||||||
|
|
||||||
roomPreviewNoPreviewJoin.setOnClickListener {
|
roomPreviewNoPreviewJoin.callback = object : ButtonStateView.Callback {
|
||||||
vectorBaseActivity.notImplemented("Join from preview")
|
override fun onButtonClicked() {
|
||||||
|
roomPreviewViewModel.joinRoom()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRetryClicked() {
|
||||||
|
// Same action
|
||||||
|
onButtonClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invalidate() = withState(roomPreviewViewModel) { state ->
|
||||||
|
TransitionManager.beginDelayedTransition(roomPreviewNoPreviewRoot)
|
||||||
|
|
||||||
|
roomPreviewNoPreviewJoin.render(
|
||||||
|
when (state.roomJoinState) {
|
||||||
|
JoinState.NOT_JOINED -> ButtonStateView.State.Button
|
||||||
|
JoinState.JOINING -> ButtonStateView.State.Loading
|
||||||
|
JoinState.JOINED -> ButtonStateView.State.Loaded
|
||||||
|
JoinState.JOINING_ERROR -> ButtonStateView.State.Error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
roomPreviewNoPreviewError.setTextOrHide(errorFormatter.toHumanReadable(state.lastError))
|
||||||
|
|
||||||
|
if (state.roomJoinState == JoinState.JOINED) {
|
||||||
|
// TODO Quit this screen and open the room
|
||||||
|
vectorBaseActivity.notImplemented("Open newly join room")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 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.riotredesign.features.roomdirectory.roompreview
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||||
|
import com.airbnb.mvrx.ViewModelContext
|
||||||
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.session.Session
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
import im.vector.matrix.rx.rx
|
||||||
|
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.JoinState
|
||||||
|
import org.koin.android.ext.android.get
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
|
class RoomPreviewViewModel(initialState: RoomPreviewViewState,
|
||||||
|
private val session: Session) : VectorViewModel<RoomPreviewViewState>(initialState) {
|
||||||
|
|
||||||
|
companion object : MvRxViewModelFactory<RoomPreviewViewModel, RoomPreviewViewState> {
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
override fun create(viewModelContext: ViewModelContext, state: RoomPreviewViewState): RoomPreviewViewModel? {
|
||||||
|
val currentSession = viewModelContext.activity.get<Session>()
|
||||||
|
|
||||||
|
return RoomPreviewViewModel(state, currentSession)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Observe joined room (from the sync)
|
||||||
|
observeJoinedRooms()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun observeJoinedRooms() {
|
||||||
|
session
|
||||||
|
.rx()
|
||||||
|
.liveRoomSummaries()
|
||||||
|
.execute { async ->
|
||||||
|
val isRoomJoined = async.invoke()
|
||||||
|
// Keep only joined room
|
||||||
|
?.filter { it.membership == Membership.JOIN }
|
||||||
|
?.map { it.roomId }
|
||||||
|
?.toList()
|
||||||
|
?.contains(roomId) == true
|
||||||
|
|
||||||
|
if (isRoomJoined) {
|
||||||
|
copy(
|
||||||
|
roomJoinState = JoinState.JOINED
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// TODO No change...
|
||||||
|
copy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO I should not have to do that
|
||||||
|
fun init(roomId: String) = withState {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomId = roomId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun joinRoom() = withState { state ->
|
||||||
|
if (state.roomJoinState == JoinState.JOINING) {
|
||||||
|
// Request already sent, should not happen
|
||||||
|
Timber.w("Try to join an already joining room. Should not happen")
|
||||||
|
return@withState
|
||||||
|
}
|
||||||
|
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomJoinState = JoinState.JOINING,
|
||||||
|
lastError = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
session.joinRoom(state.roomId, object : MatrixCallback<Unit> {
|
||||||
|
override fun onSuccess(data: Unit) {
|
||||||
|
// We do not update the joiningRoomsIds here, because, the room is not joined yet regarding the sync data.
|
||||||
|
// Instead, we wait for the room to be joined
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(failure: Throwable) {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
roomJoinState = JoinState.JOINING_ERROR,
|
||||||
|
lastError = failure
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 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.riotredesign.features.roomdirectory.roompreview
|
||||||
|
|
||||||
|
import com.airbnb.mvrx.MvRxState
|
||||||
|
import im.vector.riotredesign.features.roomdirectory.JoinState
|
||||||
|
|
||||||
|
data class RoomPreviewViewState(
|
||||||
|
// The room id
|
||||||
|
val roomId: String = "",
|
||||||
|
// Current state of the room in preview
|
||||||
|
val roomJoinState: JoinState = JoinState.NOT_JOINED,
|
||||||
|
// Last error of join room request
|
||||||
|
val lastError: Throwable? = null
|
||||||
|
) : MvRxState
|
|
@ -1,5 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/roomPreviewNoPreviewRoot"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
@ -64,15 +66,31 @@
|
||||||
android:textAppearance="@style/TextAppearance.Vector.Subtitle2"
|
android:textAppearance="@style/TextAppearance.Vector.Subtitle2"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/roomPreviewNoPreviewJoin"
|
android:id="@+id/roomPreviewNoPreviewError"
|
||||||
style="@style/VectorButtonStyle"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="@color/vector_error_color"
|
||||||
|
android:textSize="15sp"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:text="Error"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
<im.vector.riotredesign.core.platform.ButtonStateView
|
||||||
|
android:id="@+id/roomPreviewNoPreviewJoin"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
android:layout_marginBottom="@dimen/layout_vertical_margin"
|
android:layout_marginBottom="@dimen/layout_vertical_margin"
|
||||||
android:minWidth="120dp"
|
android:minWidth="120dp"
|
||||||
android:text="@string/join" />
|
app:bsv_button_text="@string/join"
|
||||||
|
app:bsv_loaded_image_src="@drawable/ic_tick"
|
||||||
|
app:bsv_use_flat_button="false"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/itemPublicRoomBottomSeparator" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_marginRight="8dp"
|
android:layout_marginRight="8dp"
|
||||||
|
app:bsv_use_flat_button="true"
|
||||||
app:bsv_button_text="@string/join"
|
app:bsv_button_text="@string/join"
|
||||||
app:bsv_loaded_image_src="@drawable/ic_tick"
|
app:bsv_loaded_image_src="@drawable/ic_tick"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/itemPublicRoomBottomSeparator"
|
app:layout_constraintBottom_toTopOf="@+id/itemPublicRoomBottomSeparator"
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
tools:parentTag="android.widget.FrameLayout">
|
tools:parentTag="android.widget.FrameLayout">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/buttonStateButton"
|
android:id="@+id/buttonStateButtonFlat"
|
||||||
style="@style/VectorButtonStyleFlat"
|
style="@style/VectorButtonStyleFlat"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -17,6 +17,18 @@
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="@string/join" />
|
tools:text="@string/join" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/buttonStateButtonBig"
|
||||||
|
style="@style/VectorButtonStyle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:minWidth="120dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/itemPublicRoomBottomSeparator"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="@string/join" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/buttonStateLoading"
|
android:id="@+id/buttonStateLoading"
|
||||||
android:layout_width="32dp"
|
android:layout_width="32dp"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
<declare-styleable name="ButtonStateView">
|
<declare-styleable name="ButtonStateView">
|
||||||
|
|
||||||
|
<attr name="bsv_use_flat_button" format="boolean" />
|
||||||
<attr name="bsv_loaded_image_src" format="reference" />
|
<attr name="bsv_loaded_image_src" format="reference" />
|
||||||
<attr name="bsv_button_text" format="reference|string" />
|
<attr name="bsv_button_text" format="reference|string" />
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue