mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 05:31:21 +03:00
Share: start managing multi selection and warning
This commit is contained in:
parent
41f1ec5d88
commit
6471787232
15 changed files with 151 additions and 40 deletions
|
@ -88,7 +88,13 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".features.share.IncomingShareActivity">
|
||||
<activity
|
||||
android:name=".features.share.IncomingShareActivity"
|
||||
android:parentActivityName=".features.home.HomeActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".features.home.HomeActivity" />
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<data android:mimeType="*/*" />
|
||||
|
|
|
@ -154,6 +154,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
|
|||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||
import kotlinx.android.synthetic.main.merge_composer_layout.*
|
||||
import kotlinx.android.synthetic.main.merge_composer_layout.view.*
|
||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||
import org.commonmark.parser.Parser
|
||||
|
@ -300,7 +301,9 @@ class RoomDetailFragment @Inject constructor(
|
|||
super.onActivityCreated(savedInstanceState)
|
||||
if (savedInstanceState == null) {
|
||||
when (val sharedData = roomDetailArgs.sharedData) {
|
||||
is SharedData.Text -> roomDetailViewModel.handle(RoomDetailAction.SendMessage(sharedData.text, false))
|
||||
is SharedData.Text -> {
|
||||
roomDetailViewModel.handle(RoomDetailAction.ExitSpecialMode(composerLayout.text.toString()))
|
||||
}
|
||||
is SharedData.Attachments -> roomDetailViewModel.handle(RoomDetailAction.SendMedia(sharedData.attachmentData))
|
||||
null -> Timber.v("No share data to process")
|
||||
}
|
||||
|
|
|
@ -16,17 +16,20 @@
|
|||
|
||||
package im.vector.riotx.features.home.room.list
|
||||
|
||||
import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
|
||||
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||
import im.vector.riotx.features.share.SharedData
|
||||
|
||||
sealed class RoomListAction : VectorViewModelAction {
|
||||
data class SelectRoom(val roomSummary: RoomSummary) : RoomListAction()
|
||||
data class SelectRoom(val roomSummary: RoomSummary, val enableMultiSelect: Boolean) : RoomListAction()
|
||||
data class ToggleCategory(val category: RoomCategory) : RoomListAction()
|
||||
data class AcceptInvitation(val roomSummary: RoomSummary) : RoomListAction()
|
||||
data class RejectInvitation(val roomSummary: RoomSummary) : RoomListAction()
|
||||
data class FilterWith(val filter: String) : RoomListAction()
|
||||
data class ChangeRoomNotificationState(val roomId: String, val notificationState: RoomNotificationState) : RoomListAction()
|
||||
data class LeaveRoom(val roomId: String) : RoomListAction()
|
||||
data class ShareToSelectedRooms(val sharedData: SharedData, val optionalMessage: String? = null): RoomListAction()
|
||||
object MarkAllRoomsRead : RoomListAction()
|
||||
}
|
||||
|
|
|
@ -106,10 +106,15 @@ class RoomListFragment @Inject constructor(
|
|||
when (it) {
|
||||
is RoomListViewEvents.Loading -> showLoading(it.message)
|
||||
is RoomListViewEvents.Failure -> showFailure(it.throwable)
|
||||
is RoomListViewEvents.SelectRoom -> openSelectedRoom(it)
|
||||
is RoomListViewEvents.SelectRoom -> handleSelectRoom(it)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
sendShareButton.setOnClickListener { _ ->
|
||||
roomListViewModel.handle(RoomListAction.ShareToSelectedRooms(roomListParams.sharedData!!))
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
createChatFabMenu.listener = this
|
||||
|
||||
sharedActionViewModel
|
||||
|
@ -131,12 +136,19 @@ class RoomListFragment @Inject constructor(
|
|||
super.onDestroyView()
|
||||
}
|
||||
|
||||
private fun openSelectedRoom(event: RoomListViewEvents.SelectRoom) {
|
||||
private fun handleSelectRoom(event: RoomListViewEvents.SelectRoom) {
|
||||
if (roomListParams.displayMode == RoomListDisplayMode.SHARE) {
|
||||
val sharedData = roomListParams.sharedData ?: return
|
||||
navigator.openRoomForSharing(requireActivity(), event.roomId, sharedData)
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(R.string.send_attachment)
|
||||
.setMessage(getString(R.string.share_confirm_room, event.roomSummary.displayName))
|
||||
.setPositiveButton(R.string.send) { _, _ ->
|
||||
navigator.openRoomForSharing(requireActivity(), event.roomSummary.roomId, sharedData)
|
||||
}
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.show()
|
||||
} else {
|
||||
navigator.openRoom(requireActivity(), event.roomId)
|
||||
navigator.openRoom(requireActivity(), event.roomSummary.roomId)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +268,7 @@ class RoomListFragment @Inject constructor(
|
|||
is Fail -> renderFailure(state.asyncFilteredRooms.error)
|
||||
}
|
||||
roomController.update(state)
|
||||
|
||||
sendShareButton.isVisible = state.multiSelectionEnabled
|
||||
// Mark all as read menu
|
||||
when (roomListParams.displayMode) {
|
||||
RoomListDisplayMode.HOME,
|
||||
|
@ -338,22 +350,24 @@ class RoomListFragment @Inject constructor(
|
|||
if (createChatFabMenu.onBackPressed()) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// RoomSummaryController.Callback **************************************************************
|
||||
|
||||
override fun onRoomClicked(room: RoomSummary) {
|
||||
roomListViewModel.handle(RoomListAction.SelectRoom(room))
|
||||
roomListViewModel.handle(RoomListAction.SelectRoom(room, enableMultiSelect = false))
|
||||
}
|
||||
|
||||
override fun onRoomLongClicked(room: RoomSummary): Boolean {
|
||||
roomController.onRoomLongClicked()
|
||||
|
||||
RoomListQuickActionsBottomSheet
|
||||
.newInstance(room.roomId, RoomListActionsArgs.Mode.FULL)
|
||||
.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS")
|
||||
if (roomListParams.displayMode == RoomListDisplayMode.SHARE) {
|
||||
roomListViewModel.handle(RoomListAction.SelectRoom(room, enableMultiSelect = true))
|
||||
} else {
|
||||
roomController.onRoomLongClicked()
|
||||
RoomListQuickActionsBottomSheet
|
||||
.newInstance(room.roomId, RoomListActionsArgs.Mode.FULL)
|
||||
.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
package im.vector.riotx.features.home.room.list
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotx.core.platform.VectorViewEvents
|
||||
|
||||
/**
|
||||
|
@ -26,5 +27,5 @@ sealed class RoomListViewEvents : VectorViewEvents {
|
|||
data class Loading(val message: CharSequence? = null) : RoomListViewEvents()
|
||||
data class Failure(val throwable: Throwable) : RoomListViewEvents()
|
||||
|
||||
data class SelectRoom(val roomId: String) : RoomListViewEvents()
|
||||
data class SelectRoom(val roomSummary: RoomSummary) : RoomListViewEvents()
|
||||
}
|
||||
|
|
|
@ -25,9 +25,11 @@ import im.vector.matrix.android.api.session.Session
|
|||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||
import im.vector.riotx.core.extensions.exhaustive
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.core.utils.DataSource
|
||||
import im.vector.riotx.features.home.RoomListDisplayMode
|
||||
import im.vector.riotx.features.share.SharedData
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
@ -67,13 +69,38 @@ class RoomListViewModel @Inject constructor(initialState: RoomListViewState,
|
|||
is RoomListAction.MarkAllRoomsRead -> handleMarkAllRoomsRead()
|
||||
is RoomListAction.LeaveRoom -> handleLeaveRoom(action)
|
||||
is RoomListAction.ChangeRoomNotificationState -> handleChangeNotificationMode(action)
|
||||
is RoomListAction.ShareToSelectedRooms -> handleShareToSelectedRooms(action)
|
||||
}.exhaustive
|
||||
}
|
||||
|
||||
private fun handleShareToSelectedRooms(action: RoomListAction.ShareToSelectedRooms) = withState {
|
||||
val sharedData = action.sharedData
|
||||
it.selectedRoomIds.forEach { roomId ->
|
||||
val room = session.getRoom(roomId)
|
||||
if (sharedData is SharedData.Text) {
|
||||
room?.sendTextMessage(sharedData.text)
|
||||
} else if (sharedData is SharedData.Attachments) {
|
||||
room?.sendMedias(sharedData.attachmentData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE METHODS *****************************************************************************
|
||||
|
||||
private fun handleSelectRoom(action: RoomListAction.SelectRoom) {
|
||||
_viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary.roomId))
|
||||
private fun handleSelectRoom(action: RoomListAction.SelectRoom) = withState {
|
||||
if (it.multiSelectionEnabled) {
|
||||
val selectedRooms = it.selectedRoomIds
|
||||
val newSelectedRooms = if (selectedRooms.contains(action.roomSummary.roomId)) {
|
||||
selectedRooms.minus(action.roomSummary.roomId)
|
||||
} else {
|
||||
selectedRooms.plus(action.roomSummary.roomId)
|
||||
}
|
||||
setState { copy(multiSelectionEnabled = newSelectedRooms.isNotEmpty(), selectedRoomIds = newSelectedRooms) }
|
||||
} else if (action.enableMultiSelect) {
|
||||
setState { copy(multiSelectionEnabled = true, selectedRoomIds = setOf(action.roomSummary.roomId)) }
|
||||
} else {
|
||||
_viewEvents.post(RoomListViewEvents.SelectRoom(action.roomSummary))
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleToggleCategory(action: RoomListAction.ToggleCategory) = setState {
|
||||
|
|
|
@ -46,7 +46,9 @@ data class RoomListViewState(
|
|||
val isServerNoticeRoomsExpanded: Boolean = true,
|
||||
// For sharing
|
||||
val isRecentExpanded: Boolean = true,
|
||||
val isOtherExpanded: Boolean = true
|
||||
val isOtherExpanded: Boolean = true,
|
||||
val selectedRoomIds: Set<String> = emptySet(),
|
||||
val multiSelectionEnabled: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomListParams) : this(displayMode = args.displayMode)
|
||||
|
|
|
@ -77,7 +77,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||
viewState.joiningRoomsIds,
|
||||
viewState.joiningErrorRoomsIds,
|
||||
viewState.rejectingRoomsIds,
|
||||
viewState.rejectingErrorRoomsIds)
|
||||
viewState.rejectingErrorRoomsIds,
|
||||
viewState.selectedRoomIds)
|
||||
|
||||
addFilterFooter(viewState)
|
||||
}
|
||||
|
@ -85,7 +86,6 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||
private fun buildShareRooms(viewState: RoomListViewState) {
|
||||
var hasResult = false
|
||||
val roomSummaries = viewState.asyncFilteredRooms()
|
||||
|
||||
roomListNameFilter.filter = viewState.roomFilter
|
||||
|
||||
roomSummaries?.forEach { (category, summaries) ->
|
||||
|
@ -105,7 +105,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||
emptySet(),
|
||||
emptySet(),
|
||||
emptySet(),
|
||||
emptySet()
|
||||
emptySet(),
|
||||
viewState.selectedRoomIds
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +132,8 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||
viewState.joiningRoomsIds,
|
||||
viewState.joiningErrorRoomsIds,
|
||||
viewState.rejectingRoomsIds,
|
||||
viewState.rejectingErrorRoomsIds)
|
||||
viewState.rejectingErrorRoomsIds,
|
||||
viewState.selectedRoomIds)
|
||||
// Never set showHelp to true for invitation
|
||||
if (category != RoomCategory.INVITE) {
|
||||
showHelp = userPreferencesProvider.shouldShowLongClickOnRoomHelp()
|
||||
|
@ -196,10 +198,11 @@ class RoomSummaryController @Inject constructor(private val stringProvider: Stri
|
|||
joiningRoomsIds: Set<String>,
|
||||
joiningErrorRoomsIds: Set<String>,
|
||||
rejectingRoomsIds: Set<String>,
|
||||
rejectingErrorRoomsIds: Set<String>) {
|
||||
rejectingErrorRoomsIds: Set<String>,
|
||||
selectedRoomIds: Set<String>) {
|
||||
summaries.forEach { roomSummary ->
|
||||
roomSummaryItemFactory
|
||||
.create(roomSummary, joiningRoomsIds, joiningErrorRoomsIds, rejectingRoomsIds, rejectingErrorRoomsIds, listener)
|
||||
.create(roomSummary, joiningRoomsIds, joiningErrorRoomsIds, rejectingRoomsIds, rejectingErrorRoomsIds,selectedRoomIds, listener)
|
||||
.addTo(this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,17 @@
|
|||
|
||||
package im.vector.riotx.features.home.room.list
|
||||
|
||||
import android.view.HapticFeedbackConstants
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import com.amulyakhare.textdrawable.TextDrawable
|
||||
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
|
@ -48,11 +51,15 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
@EpoxyAttribute var itemLongClickListener: View.OnLongClickListener? = null
|
||||
@EpoxyAttribute var itemClickListener: View.OnClickListener? = null
|
||||
@EpoxyAttribute var showSelected: Boolean = false
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.rootView.setOnClickListener(itemClickListener)
|
||||
holder.rootView.setOnLongClickListener(itemLongClickListener)
|
||||
holder.rootView.setOnLongClickListener {
|
||||
it.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
|
||||
itemLongClickListener?.onLongClick(it) ?: false
|
||||
}
|
||||
holder.titleView.text = matrixItem.getBestName()
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
|
@ -64,6 +71,19 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
holder.roomAvatarDecorationImageView.isVisible = encryptionTrustLevel != null
|
||||
holder.roomAvatarDecorationImageView.setImageResource(encryptionTrustLevel.toImageRes())
|
||||
renderSelection(holder, showSelected)
|
||||
}
|
||||
|
||||
private fun renderSelection(holder: Holder, isSelected: Boolean) {
|
||||
if (isSelected) {
|
||||
holder.avatarCheckedImageView.visibility = View.VISIBLE
|
||||
val backgroundColor = ContextCompat.getColor(holder.view.context, R.color.riotx_accent)
|
||||
val backgroundDrawable = TextDrawable.builder().buildRound("", backgroundColor)
|
||||
holder.avatarImageView.setImageDrawable(backgroundDrawable)
|
||||
} else {
|
||||
holder.avatarCheckedImageView.visibility = View.GONE
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
}
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
@ -74,6 +94,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
val typingView by bind<TextView>(R.id.roomTypingView)
|
||||
val draftView by bind<ImageView>(R.id.roomDraftBadge)
|
||||
val lastEventTimeView by bind<TextView>(R.id.roomLastEventTimeView)
|
||||
val avatarCheckedImageView by bind<ImageView>(R.id.roomAvatarCheckedImageView)
|
||||
val avatarImageView by bind<ImageView>(R.id.roomAvatarImageView)
|
||||
val roomAvatarDecorationImageView by bind<ImageView>(R.id.roomAvatarDecorationImageView)
|
||||
val rootView by bind<ViewGroup>(R.id.itemRoomLayout)
|
||||
|
|
|
@ -36,7 +36,6 @@ import javax.inject.Inject
|
|||
|
||||
class RoomSummaryItemFactory @Inject constructor(private val displayableEventFormatter: DisplayableEventFormatter,
|
||||
private val dateFormatter: VectorDateFormatter,
|
||||
private val colorProvider: ColorProvider,
|
||||
private val stringProvider: StringProvider,
|
||||
private val typingHelper: TypingHelper,
|
||||
private val session: Session,
|
||||
|
@ -47,10 +46,11 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
joiningErrorRoomsIds: Set<String>,
|
||||
rejectingRoomsIds: Set<String>,
|
||||
rejectingErrorRoomsIds: Set<String>,
|
||||
selectedRoomIds: Set<String>,
|
||||
listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
||||
return when (roomSummary.membership) {
|
||||
Membership.INVITE -> createInvitationItem(roomSummary, joiningRoomsIds, joiningErrorRoomsIds, rejectingRoomsIds, rejectingErrorRoomsIds, listener)
|
||||
else -> createRoomItem(roomSummary, listener)
|
||||
else -> createRoomItem(roomSummary, selectedRoomIds, listener)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,10 +82,10 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
.listener { listener?.onRoomClicked(roomSummary) }
|
||||
}
|
||||
|
||||
private fun createRoomItem(roomSummary: RoomSummary, listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
||||
private fun createRoomItem(roomSummary: RoomSummary, selectedRoomIds: Set<String>, listener: RoomSummaryController.Listener?): VectorEpoxyModel<*> {
|
||||
val unreadCount = roomSummary.notificationCount
|
||||
val showHighlighted = roomSummary.highlightCount > 0
|
||||
|
||||
val showSelected = selectedRoomIds.contains(roomSummary.roomId)
|
||||
var latestFormattedEvent: CharSequence = ""
|
||||
var latestEventTime: CharSequence = ""
|
||||
val latestEvent = roomSummary.latestPreviewableEvent
|
||||
|
@ -119,6 +119,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
.typingString(typingString)
|
||||
.lastFormattedEvent(latestFormattedEvent)
|
||||
.showHighlighted(showHighlighted)
|
||||
.showSelected(showSelected)
|
||||
.unreadNotificationCount(unreadCount)
|
||||
.hasUnreadMessage(roomSummary.hasUnreadMessages)
|
||||
.hasDraft(roomSummary.userDrafts.isNotEmpty())
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.riotx.features.share
|
|||
import android.content.ClipDescription
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.Window
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import com.airbnb.mvrx.viewModel
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
style="@style/VectorToolbarStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:elevation="4dp"
|
||||
app:contentInsetStart="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
|
|
@ -55,4 +55,17 @@
|
|||
tools:layout_marginEnd="144dp"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/sendShareButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:accessibilityTraversalBefore="@+id/roomListView"
|
||||
android:contentDescription="@string/a11y_create_room"
|
||||
android:src="@drawable/ic_send"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</im.vector.riotx.core.platform.StateView>
|
||||
|
|
|
@ -21,21 +21,37 @@
|
|||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarImageView"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
<FrameLayout
|
||||
android:id="@+id/roomAvatarContainer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarImageView"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarCheckedImageView"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="56dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_material_done"
|
||||
android:tint="@android:color/white"
|
||||
android:visibility="visible" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomAvatarDecorationImageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
app:layout_constraintCircle="@+id/roomAvatarImageView"
|
||||
app:layout_constraintCircle="@id/roomAvatarContainer"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="28dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
|
@ -47,7 +63,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/roomAvatarImageView"
|
||||
app:layout_constraintTop_toBottomOf="@id/roomAvatarContainer"
|
||||
tools:layout_marginStart="20dp" />
|
||||
|
||||
<im.vector.riotx.core.platform.EllipsizingTextView
|
||||
|
@ -69,7 +85,7 @@
|
|||
app:layout_constraintEnd_toStartOf="@+id/roomDraftBadge"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toEndOf="@id/roomAvatarImageView"
|
||||
app:layout_constraintStart_toEndOf="@id/roomAvatarContainer"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@sample/matrix.json/data/displayName" />
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
<!-- BEGIN Strings added by Benoit -->
|
||||
<string name="message_action_item_redact">Remove…</string>
|
||||
<string name="share_confirm_room">Do you want to send this attachment to %1$s?</string>
|
||||
<!-- END Strings added by Benoit -->
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue