mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Device list: remove the detail dialog: handle the actions directly in the list
This commit is contained in:
parent
6b2703f6ce
commit
8dff196716
@ -18,13 +18,18 @@ package im.vector.riotx.features.settings.devices
|
|||||||
|
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list item for Device.
|
* A list item for Device.
|
||||||
@ -36,29 +41,69 @@ abstract class DeviceItem : VectorEpoxyModel<DeviceItem.Holder>() {
|
|||||||
lateinit var deviceInfo: DeviceInfo
|
lateinit var deviceInfo: DeviceInfo
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var bold = false
|
var currentDevice = false
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var buttonsVisible = false
|
||||||
|
|
||||||
@EpoxyAttribute
|
@EpoxyAttribute
|
||||||
var itemClickAction: (() -> Unit)? = null
|
var itemClickAction: (() -> Unit)? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var renameClickAction: (() -> Unit)? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var deleteClickAction: (() -> Unit)? = null
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
override fun bind(holder: Holder) {
|
||||||
holder.root.setOnClickListener { itemClickAction?.invoke() }
|
holder.root.setOnClickListener { itemClickAction?.invoke() }
|
||||||
|
|
||||||
holder.displayNameText.text = deviceInfo.displayName ?: ""
|
holder.displayNameText.text = deviceInfo.displayName ?: ""
|
||||||
holder.deviceIdText.text = deviceInfo.deviceId ?: ""
|
holder.deviceIdText.text = deviceInfo.deviceId ?: ""
|
||||||
|
|
||||||
if (bold) {
|
val lastSeenIp = deviceInfo.lastSeenIp?.takeIf { ip -> ip.isNotBlank() } ?: "-"
|
||||||
holder.displayNameText.setTypeface(null, Typeface.BOLD)
|
|
||||||
holder.deviceIdText.setTypeface(null, Typeface.BOLD)
|
val lastSeenTime = deviceInfo.lastSeenTs?.let { ts ->
|
||||||
} else {
|
val dateFormatTime = SimpleDateFormat("HH:mm:ss", Locale.ROOT)
|
||||||
holder.displayNameText.setTypeface(null, Typeface.NORMAL)
|
val date = Date(ts)
|
||||||
holder.deviceIdText.setTypeface(null, Typeface.NORMAL)
|
|
||||||
|
val time = dateFormatTime.format(date)
|
||||||
|
val dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault())
|
||||||
|
|
||||||
|
dateFormat.format(date) + ", " + time
|
||||||
|
} ?: "-"
|
||||||
|
|
||||||
|
holder.deviceLastSeenText.text = holder.root.context.getString(R.string.devices_details_last_seen_format, lastSeenIp, lastSeenTime)
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
holder.displayNameLabelText,
|
||||||
|
holder.displayNameText,
|
||||||
|
holder.deviceIdLabelText,
|
||||||
|
holder.deviceIdText,
|
||||||
|
holder.deviceLastSeenLabelText,
|
||||||
|
holder.deviceLastSeenText
|
||||||
|
).map {
|
||||||
|
it.setTypeface(null, if (currentDevice) Typeface.BOLD else Typeface.NORMAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
holder.buttonDelete.isVisible = !currentDevice
|
||||||
|
|
||||||
|
holder.buttons.isVisible = buttonsVisible
|
||||||
|
|
||||||
|
holder.buttonRename.setOnClickListener { renameClickAction?.invoke() }
|
||||||
|
holder.buttonDelete.setOnClickListener { deleteClickAction?.invoke() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Holder : VectorEpoxyHolder() {
|
class Holder : VectorEpoxyHolder() {
|
||||||
val root by bind<View>(R.id.itemDeviceRoot)
|
val root by bind<ViewGroup>(R.id.itemDeviceRoot)
|
||||||
|
val displayNameLabelText by bind<TextView>(R.id.itemDeviceDisplayNameLabel)
|
||||||
val displayNameText by bind<TextView>(R.id.itemDeviceDisplayName)
|
val displayNameText by bind<TextView>(R.id.itemDeviceDisplayName)
|
||||||
|
val deviceIdLabelText by bind<TextView>(R.id.itemDeviceIdLabel)
|
||||||
val deviceIdText by bind<TextView>(R.id.itemDeviceId)
|
val deviceIdText by bind<TextView>(R.id.itemDeviceId)
|
||||||
|
val deviceLastSeenLabelText by bind<TextView>(R.id.itemDeviceLastSeenLabel)
|
||||||
|
val deviceLastSeenText by bind<TextView>(R.id.itemDeviceLastSeen)
|
||||||
|
val buttons by bind<View>(R.id.itemDeviceButtons)
|
||||||
|
val buttonDelete by bind<View>(R.id.itemDeviceDelete)
|
||||||
|
val buttonRename by bind<View>(R.id.itemDeviceRename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,8 +72,11 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
|
|||||||
deviceItem {
|
deviceItem {
|
||||||
id("device$idx")
|
id("device$idx")
|
||||||
deviceInfo(deviceInfo)
|
deviceInfo(deviceInfo)
|
||||||
bold(isCurrentDevice)
|
currentDevice(isCurrentDevice)
|
||||||
itemClickAction { callback?.onDeviceClicked(deviceInfo, isCurrentDevice) }
|
buttonsVisible(deviceInfo.deviceId == state.currentExpandedDeviceId)
|
||||||
|
itemClickAction { callback?.onDeviceClicked(deviceInfo) }
|
||||||
|
renameClickAction { callback?.onRenameDevice(deviceInfo) }
|
||||||
|
deleteClickAction { callback?.onDeleteDevice(deviceInfo) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,8 +84,8 @@ class DevicesController @Inject constructor(private val errorFormatter: ErrorFor
|
|||||||
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
fun retry()
|
fun retry()
|
||||||
fun onDeviceClicked(deviceInfo: DeviceInfo, isCurrentDevice: Boolean)
|
fun onDeviceClicked(deviceInfo: DeviceInfo)
|
||||||
|
fun onRenameDevice(deviceInfo: DeviceInfo)
|
||||||
|
fun onDeleteDevice(deviceInfo: DeviceInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import timber.log.Timber
|
|||||||
data class DevicesViewState(
|
data class DevicesViewState(
|
||||||
val myDeviceId: String = "",
|
val myDeviceId: String = "",
|
||||||
val devices: Async<List<DeviceInfo>> = Uninitialized,
|
val devices: Async<List<DeviceInfo>> = Uninitialized,
|
||||||
|
val currentExpandedDeviceId: String? = null,
|
||||||
val request: Async<Unit> = Uninitialized
|
val request: Async<Unit> = Uninitialized
|
||||||
) : MvRxState
|
) : MvRxState
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ sealed class DevicesAction : VectorViewModelAction {
|
|||||||
data class Delete(val deviceInfo: DeviceInfo) : DevicesAction()
|
data class Delete(val deviceInfo: DeviceInfo) : DevicesAction()
|
||||||
data class Password(val password: String) : DevicesAction()
|
data class Password(val password: String) : DevicesAction()
|
||||||
data class Rename(val deviceInfo: DeviceInfo, val newName: String) : DevicesAction()
|
data class Rename(val deviceInfo: DeviceInfo, val newName: String) : DevicesAction()
|
||||||
|
data class ToggleDevice(val deviceInfo: DeviceInfo) : DevicesAction()
|
||||||
}
|
}
|
||||||
|
|
||||||
class DevicesViewModel @AssistedInject constructor(@Assisted initialState: DevicesViewState,
|
class DevicesViewModel @AssistedInject constructor(@Assisted initialState: DevicesViewState,
|
||||||
@ -114,10 +116,21 @@ class DevicesViewModel @AssistedInject constructor(@Assisted initialState: Devic
|
|||||||
|
|
||||||
override fun handle(action: DevicesAction) {
|
override fun handle(action: DevicesAction) {
|
||||||
return when (action) {
|
return when (action) {
|
||||||
is DevicesAction.Retry -> refreshDevicesList()
|
is DevicesAction.Retry -> refreshDevicesList()
|
||||||
is DevicesAction.Delete -> handleDelete(action)
|
is DevicesAction.Delete -> handleDelete(action)
|
||||||
is DevicesAction.Password -> handlePassword(action)
|
is DevicesAction.Password -> handlePassword(action)
|
||||||
is DevicesAction.Rename -> handleRename(action)
|
is DevicesAction.Rename -> handleRename(action)
|
||||||
|
is DevicesAction.ToggleDevice -> handleToggleDevice(action)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleToggleDevice(action: DevicesAction.ToggleDevice) {
|
||||||
|
withState {
|
||||||
|
setState {
|
||||||
|
copy(
|
||||||
|
currentExpandedDeviceId = if (it.currentExpandedDeviceId == action.deviceInfo.deviceId) null else action.deviceInfo.deviceId
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import android.os.Bundle
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.TextView
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.airbnb.mvrx.Async
|
import com.airbnb.mvrx.Async
|
||||||
@ -36,12 +35,8 @@ import im.vector.riotx.core.extensions.observeEvent
|
|||||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||||
import im.vector.riotx.core.utils.toast
|
import im.vector.riotx.core.utils.toast
|
||||||
import im.vector.riotx.features.settings.VectorSettingsSecurityPrivacyFragment
|
|
||||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||||
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
import kotlinx.android.synthetic.main.merge_overlay_waiting_view.*
|
||||||
import java.text.DateFormat
|
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,63 +92,22 @@ class VectorSettingsDevicesFragment @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a dialog containing the device ID, the device name and the "last seen" information.<>
|
* Display a dialog containing the device ID, the device name and the "last seen" information.
|
||||||
* This dialog allow to delete the corresponding device (see [.displayDeviceDeletionDialog])
|
* This dialog allow to delete the corresponding device (see [.displayDeviceDeletionDialog])
|
||||||
*
|
*
|
||||||
* @param deviceInfo the device information
|
* @param deviceInfo the device information
|
||||||
* @param isCurrentDevice true if this is the current device
|
* @param isCurrentDevice true if this is the current device
|
||||||
*/
|
*/
|
||||||
override fun onDeviceClicked(deviceInfo: DeviceInfo, isCurrentDevice: Boolean) {
|
override fun onDeviceClicked(deviceInfo: DeviceInfo) {
|
||||||
val builder = AlertDialog.Builder(requireActivity())
|
devicesViewModel.handle(DevicesAction.ToggleDevice(deviceInfo))
|
||||||
val inflater = requireActivity().layoutInflater
|
}
|
||||||
val layout = inflater.inflate(R.layout.dialog_device_details, null)
|
|
||||||
var textView = layout.findViewById<TextView>(R.id.device_id)
|
|
||||||
|
|
||||||
textView.text = deviceInfo.deviceId
|
override fun onDeleteDevice(deviceInfo: DeviceInfo) {
|
||||||
|
devicesViewModel.handle(DevicesAction.Delete(deviceInfo))
|
||||||
|
}
|
||||||
|
|
||||||
// device name
|
override fun onRenameDevice(deviceInfo: DeviceInfo) {
|
||||||
textView = layout.findViewById(R.id.device_name)
|
displayDeviceRenameDialog(deviceInfo)
|
||||||
val displayName = if (deviceInfo.displayName.isNullOrEmpty()) VectorSettingsSecurityPrivacyFragment.LABEL_UNAVAILABLE_DATA else deviceInfo.displayName
|
|
||||||
textView.text = displayName
|
|
||||||
|
|
||||||
// last seen info
|
|
||||||
textView = layout.findViewById(R.id.device_last_seen)
|
|
||||||
|
|
||||||
val lastSeenIp = deviceInfo.lastSeenIp?.takeIf { ip -> ip.isNotBlank() } ?: "-"
|
|
||||||
|
|
||||||
val lastSeenTime = deviceInfo.lastSeenTs?.let { ts ->
|
|
||||||
val dateFormatTime = SimpleDateFormat("HH:mm:ss", Locale.ROOT)
|
|
||||||
val date = Date(ts)
|
|
||||||
|
|
||||||
val time = dateFormatTime.format(date)
|
|
||||||
val dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault())
|
|
||||||
|
|
||||||
dateFormat.format(date) + ", " + time
|
|
||||||
} ?: "-"
|
|
||||||
|
|
||||||
val lastSeenInfo = getString(R.string.devices_details_last_seen_format, lastSeenIp, lastSeenTime)
|
|
||||||
textView.text = lastSeenInfo
|
|
||||||
|
|
||||||
// title & icon
|
|
||||||
builder.setTitle(R.string.devices_details_dialog_title)
|
|
||||||
.setIcon(android.R.drawable.ic_dialog_info)
|
|
||||||
.setView(layout)
|
|
||||||
.setPositiveButton(R.string.rename) { _, _ -> displayDeviceRenameDialog(deviceInfo) }
|
|
||||||
|
|
||||||
// disable the deletion for our own device
|
|
||||||
if (!isCurrentDevice) {
|
|
||||||
builder.setNegativeButton(R.string.delete) { _, _ -> devicesViewModel.handle(DevicesAction.Delete(deviceInfo)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.setNeutralButton(R.string.cancel, null)
|
|
||||||
.setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event ->
|
|
||||||
if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
|
|
||||||
dialog.cancel()
|
|
||||||
return@OnKeyListener true
|
|
||||||
}
|
|
||||||
false
|
|
||||||
})
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun retry() {
|
override fun retry() {
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<ScrollView 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">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/device_container_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingStart="?dialogPreferredPadding"
|
|
||||||
android:paddingLeft="?dialogPreferredPadding"
|
|
||||||
android:paddingTop="12dp"
|
|
||||||
android:paddingEnd="?dialogPreferredPadding"
|
|
||||||
android:paddingRight="?dialogPreferredPadding">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_id_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="@string/devices_details_id_title"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_id"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp"
|
|
||||||
tools:text="a device id" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_name_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="@string/devices_details_name_title"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_name"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp"
|
|
||||||
tools:text="a device name" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_last_seen_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="@string/devices_details_last_seen_title"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/device_last_seen"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="12sp"
|
|
||||||
tools:text="x.x.x.x @ 01/01 00:00:00" />
|
|
||||||
</LinearLayout>
|
|
||||||
</ScrollView>
|
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout 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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/itemDeviceRoot"
|
android:id="@+id/itemDeviceRoot"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -13,32 +12,87 @@
|
|||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:paddingBottom="8dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/itemDeviceDisplayNameLabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:text="@string/devices_details_name_title"
|
||||||
|
android:textColor="?riotx_text_secondary"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/itemDeviceDisplayName"
|
android:id="@+id/itemDeviceDisplayName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?riotx_text_primary"
|
android:textColor="?riotx_text_primary"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/itemUserName"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/itemUserAvatar"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
|
||||||
tools:text="Android phone" />
|
tools:text="Android phone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/itemDeviceIdLabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:text="@string/devices_details_id_title"
|
||||||
|
android:textColor="?riotx_text_secondary"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/itemDeviceId"
|
android:id="@+id/itemDeviceId"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textColor="?riotx_text_secondary"
|
android:textColor="?riotx_text_primary"
|
||||||
android:textSize="15sp"
|
android:textSize="15sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/itemUserAvatar"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/itemUserId"
|
|
||||||
tools:text="XUIDERFZAA" />
|
tools:text="XUIDERFZAA" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/itemDeviceLastSeenLabel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:text="@string/devices_details_last_seen_title"
|
||||||
|
android:textColor="?riotx_text_secondary"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/itemDeviceLastSeen"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="?riotx_text_primary"
|
||||||
|
android:textSize="15sp"
|
||||||
|
tools:text="x.x.x.x @ 01/01 00:00:00" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/itemDeviceButtons"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/itemDeviceRename"
|
||||||
|
style="@style/VectorButtonStyleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/rename" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/itemDeviceDelete"
|
||||||
|
style="@style/VectorButtonStyleText"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/delete"
|
||||||
|
android:textColor="@color/riotx_notice"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user