This commit is contained in:
Benoit Marty 2020-06-30 15:52:40 +02:00
parent e0ea0c195b
commit cca6d0e967
13 changed files with 88 additions and 87 deletions

View File

@ -23,6 +23,7 @@ import im.vector.matrix.android.api.session.room.Room
import im.vector.matrix.android.api.session.room.members.RoomMemberQueryParams import im.vector.matrix.android.api.session.room.members.RoomMemberQueryParams
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
import im.vector.matrix.android.api.session.room.model.ReadReceipt import im.vector.matrix.android.api.session.room.model.ReadReceipt
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
import im.vector.matrix.android.api.session.room.model.RoomSummary import im.vector.matrix.android.api.session.room.model.RoomSummary
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
@ -119,7 +120,7 @@ class RxRoom(private val room: Room) {
room.updateCanonicalAlias(alias, it) room.updateCanonicalAlias(alias, it)
} }
fun updateHistoryReadability(readability: String) = completableBuilder<Unit> { fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = completableBuilder<Unit> {
room.updateHistoryReadability(readability, it) room.updateHistoryReadability(readability, it)
} }

View File

@ -21,6 +21,7 @@ import androidx.lifecycle.LiveData
import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.query.QueryStringValue import im.vector.matrix.android.api.query.QueryStringValue
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
@ -50,7 +51,7 @@ interface StateService {
/** /**
* Update the history readability of the room * Update the history readability of the room
*/ */
fun updateHistoryReadability(readability: String, callback: MatrixCallback<Unit>): Cancelable fun updateHistoryReadability(readability: RoomHistoryVisibility, callback: MatrixCallback<Unit>): Cancelable
/** /**
* Update the avatar of the room * Update the avatar of the room

View File

@ -28,8 +28,6 @@ import im.vector.matrix.android.api.util.JsonDict
import im.vector.matrix.android.api.util.Optional import im.vector.matrix.android.api.util.Optional
import im.vector.matrix.android.internal.database.model.UserThreePidEntity import im.vector.matrix.android.internal.database.model.UserThreePidEntity
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.di.SessionId
import im.vector.matrix.android.internal.di.WorkManagerProvider
import im.vector.matrix.android.internal.session.content.FileUploader import im.vector.matrix.android.internal.session.content.FileUploader
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith import im.vector.matrix.android.internal.task.configureWith
@ -38,12 +36,8 @@ import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import io.realm.kotlin.where import io.realm.kotlin.where
import javax.inject.Inject import javax.inject.Inject
private const val UPLOAD_AVATAR_WORK = "UPLOAD_AVATAR_WORK"
internal class DefaultProfileService @Inject constructor(private val taskExecutor: TaskExecutor, internal class DefaultProfileService @Inject constructor(private val taskExecutor: TaskExecutor,
@SessionDatabase private val monarchy: Monarchy, @SessionDatabase private val monarchy: Monarchy,
@SessionId private val sessionId: String,
private val workManagerProvider: WorkManagerProvider,
private val coroutineDispatchers: MatrixCoroutineDispatchers, private val coroutineDispatchers: MatrixCoroutineDispatchers,
private val refreshUserThreePidsTask: RefreshUserThreePidsTask, private val refreshUserThreePidsTask: RefreshUserThreePidsTask,
private val getProfileInfoTask: GetProfileInfoTask, private val getProfileInfoTask: GetProfileInfoTask,

View File

@ -24,6 +24,7 @@ import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.query.QueryStringValue import im.vector.matrix.android.api.query.QueryStringValue
import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
import im.vector.matrix.android.api.session.room.state.StateService import im.vector.matrix.android.api.session.room.state.StateService
import im.vector.matrix.android.api.util.Cancelable import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.api.util.JsonDict import im.vector.matrix.android.api.util.JsonDict
@ -35,8 +36,6 @@ import im.vector.matrix.android.internal.task.configureWith
import im.vector.matrix.android.internal.task.launchToCallback import im.vector.matrix.android.internal.task.launchToCallback
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
private const val UPLOAD_AVATAR_WORK = "UPLOAD_AVATAR_WORK"
internal class DefaultStateService @AssistedInject constructor(@Assisted private val roomId: String, internal class DefaultStateService @AssistedInject constructor(@Assisted private val roomId: String,
private val stateEventDataSource: StateEventDataSource, private val stateEventDataSource: StateEventDataSource,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
@ -121,7 +120,7 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private
) )
} }
override fun updateHistoryReadability(readability: String, callback: MatrixCallback<Unit>): Cancelable { override fun updateHistoryReadability(readability: RoomHistoryVisibility, callback: MatrixCallback<Unit>): Cancelable {
return sendStateEvent( return sendStateEvent(
eventType = EventType.STATE_ROOM_HISTORY_VISIBILITY, eventType = EventType.STATE_ROOM_HISTORY_VISIBILITY,
body = mapOf("history_visibility" to readability), body = mapOf("history_visibility" to readability),

View File

@ -97,15 +97,15 @@ class BigImageViewerActivity : VectorBaseActivity() {
} }
private fun showAvatarSelector() { private fun showAvatarSelector() {
AlertDialog AlertDialog.Builder(this)
.Builder(this)
.setItems(arrayOf( .setItems(arrayOf(
stringProvider.getString(R.string.attachment_type_camera), stringProvider.getString(R.string.attachment_type_camera),
stringProvider.getString(R.string.attachment_type_gallery) stringProvider.getString(R.string.attachment_type_gallery)
)) { dialog, which -> )) { dialog, which ->
dialog.cancel() dialog.cancel()
onAvatarTypeSelected(isCamera = (which == 0)) onAvatarTypeSelected(isCamera = (which == 0))
}.show() }
.show()
} }
private var avatarCameraUri: Uri? = null private var avatarCameraUri: Uri? = null

View File

@ -46,7 +46,6 @@ import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.extensions.setTextOrHide import im.vector.riotx.core.extensions.setTextOrHide
import im.vector.riotx.core.intent.getFilenameFromUri import im.vector.riotx.core.intent.getFilenameFromUri
import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.core.resources.ColorProvider
import im.vector.riotx.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.riotx.core.utils.PERMISSIONS_FOR_TAKING_PHOTO
import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA import im.vector.riotx.core.utils.PERMISSION_REQUEST_CODE_LAUNCH_CAMERA
import im.vector.riotx.core.utils.allGranted import im.vector.riotx.core.utils.allGranted
@ -78,8 +77,7 @@ data class RoomProfileArgs(
class RoomProfileFragment @Inject constructor( class RoomProfileFragment @Inject constructor(
private val roomProfileController: RoomProfileController, private val roomProfileController: RoomProfileController,
private val avatarRenderer: AvatarRenderer, private val avatarRenderer: AvatarRenderer,
val roomProfileViewModelFactory: RoomProfileViewModel.Factory, val roomProfileViewModelFactory: RoomProfileViewModel.Factory
val colorProvider: ColorProvider
) : VectorBaseFragment(), RoomProfileController.Callback { ) : VectorBaseFragment(), RoomProfileController.Callback {
private val roomProfileArgs: RoomProfileArgs by args() private val roomProfileArgs: RoomProfileArgs by args()
@ -253,15 +251,15 @@ class RoomProfileFragment @Inject constructor(
} }
private fun showAvatarSelector() { private fun showAvatarSelector() {
AlertDialog AlertDialog.Builder(requireContext())
.Builder(requireContext())
.setItems(arrayOf( .setItems(arrayOf(
getString(R.string.attachment_type_camera), getString(R.string.attachment_type_camera),
getString(R.string.attachment_type_gallery) getString(R.string.attachment_type_gallery)
)) { dialog, which -> )) { dialog, which ->
dialog.cancel() dialog.cancel()
onAvatarTypeSelected(isCamera = (which == 0)) onAvatarTypeSelected(isCamera = (which == 0))
}.show() }
.show()
} }
private var avatarCameraUri: Uri? = null private var avatarCameraUri: Uri? = null

View File

@ -68,10 +68,12 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable()
powerLevelsContentLive.subscribe { powerLevelsContentLive
.subscribe {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
setState { copy(canChangeAvatar = powerLevelsHelper.isUserAbleToChangeRoomAvatar(session.myUserId)) } setState { copy(canChangeAvatar = powerLevelsHelper.isUserAbleToChangeRoomAvatar(session.myUserId)) }
}.disposeOnClear() }
.disposeOnClear()
} }
override fun handle(action: RoomProfileAction) = when (action) { override fun handle(action: RoomProfileAction) = when (action) {
@ -111,9 +113,11 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
private fun handleChangeAvatar(action: RoomProfileAction.ChangeRoomAvatar) { private fun handleChangeAvatar(action: RoomProfileAction.ChangeRoomAvatar) {
_viewEvents.post(RoomProfileViewEvents.Loading()) _viewEvents.post(RoomProfileViewEvents.Loading())
room.rx().updateAvatar(action.uri, action.fileName ?: UUID.randomUUID().toString()) room.rx().updateAvatar(action.uri, action.fileName ?: UUID.randomUUID().toString())
.subscribe({ .subscribe(
{
_viewEvents.post(RoomProfileViewEvents.OnChangeAvatarSuccess) _viewEvents.post(RoomProfileViewEvents.OnChangeAvatarSuccess)
}, { },
{
_viewEvents.post(RoomProfileViewEvents.Failure(it)) _viewEvents.post(RoomProfileViewEvents.Failure(it))
}) })
.disposeOnClear() .disposeOnClear()

View File

@ -86,7 +86,7 @@ class RoomSettingsController @Inject constructor(
formEditTextItem { formEditTextItem {
id("alias") id("alias")
enabled(data.actionPermissions.canChangeCanonicalAlias) enabled(data.actionPermissions.canChangeCanonicalAlias)
value(data.newAlias ?: roomSummary.canonicalAlias) value(data.newCanonicalAlias ?: roomSummary.canonicalAlias)
hint(stringProvider.getString(R.string.room_settings_addresses_add_new_address)) hint(stringProvider.getString(R.string.room_settings_addresses_add_new_address))
onTextChange { text -> onTextChange { text ->

View File

@ -34,7 +34,6 @@ import im.vector.riotx.core.extensions.cleanup
import im.vector.riotx.core.extensions.configureWith import im.vector.riotx.core.extensions.configureWith
import im.vector.riotx.core.extensions.exhaustive import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.platform.VectorBaseFragment import im.vector.riotx.core.platform.VectorBaseFragment
import im.vector.riotx.core.resources.StringProvider
import im.vector.riotx.core.utils.toast import im.vector.riotx.core.utils.toast
import im.vector.riotx.features.home.AvatarRenderer import im.vector.riotx.features.home.AvatarRenderer
import im.vector.riotx.features.roomprofile.RoomProfileArgs import im.vector.riotx.features.roomprofile.RoomProfileArgs
@ -45,8 +44,7 @@ import javax.inject.Inject
class RoomSettingsFragment @Inject constructor( class RoomSettingsFragment @Inject constructor(
val viewModelFactory: RoomSettingsViewModel.Factory, val viewModelFactory: RoomSettingsViewModel.Factory,
private val controller: RoomSettingsController, private val controller: RoomSettingsController,
private val avatarRenderer: AvatarRenderer, private val avatarRenderer: AvatarRenderer
private val stringProvider: StringProvider
) : VectorBaseFragment(), RoomSettingsController.Callback { ) : VectorBaseFragment(), RoomSettingsController.Callback {
private val viewModel: RoomSettingsViewModel by fragmentViewModel() private val viewModel: RoomSettingsViewModel by fragmentViewModel()
@ -154,12 +152,13 @@ class RoomSettingsFragment @Inject constructor(
return@withState return@withState
} }
// TODO Create a formatter for this enum, it's done 3 times in the project
private fun formatHistoryVisibility(historyVisibility: RoomHistoryVisibility): String { private fun formatHistoryVisibility(historyVisibility: RoomHistoryVisibility): String {
return when (historyVisibility) { return when (historyVisibility) {
RoomHistoryVisibility.SHARED -> stringProvider.getString(R.string.notice_room_visibility_shared) RoomHistoryVisibility.SHARED -> getString(R.string.notice_room_visibility_shared)
RoomHistoryVisibility.INVITED -> stringProvider.getString(R.string.notice_room_visibility_invited) RoomHistoryVisibility.INVITED -> getString(R.string.notice_room_visibility_invited)
RoomHistoryVisibility.JOINED -> stringProvider.getString(R.string.notice_room_visibility_joined) RoomHistoryVisibility.JOINED -> getString(R.string.notice_room_visibility_joined)
RoomHistoryVisibility.WORLD_READABLE -> stringProvider.getString(R.string.notice_room_visibility_world_readable) RoomHistoryVisibility.WORLD_READABLE -> getString(R.string.notice_room_visibility_world_readable)
} }
} }

View File

@ -27,11 +27,11 @@ import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.matrix.rx.unwrap import im.vector.matrix.rx.unwrap
import im.vector.riotx.core.extensions.exhaustive
import im.vector.riotx.core.platform.VectorViewModel import im.vector.riotx.core.platform.VectorViewModel
import im.vector.riotx.features.powerlevel.PowerLevelsObservableFactory import im.vector.riotx.features.powerlevel.PowerLevelsObservableFactory
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Observable import io.reactivex.Observable
import java.util.Locale
class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState, class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState: RoomSettingsViewState,
private val session: Session) private val session: Session)
@ -55,6 +55,30 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
init { init {
observeRoomSummary() observeRoomSummary()
observeState()
}
private fun observeState() {
selectSubscribe(
RoomSettingsViewState::newName,
RoomSettingsViewState::newCanonicalAlias,
RoomSettingsViewState::newTopic,
RoomSettingsViewState::newHistoryVisibility,
RoomSettingsViewState::roomSummary) { newName,
newAlias,
newTopic,
newHistoryVisibility,
asyncSummary ->
val summary = asyncSummary()
setState {
copy(
showSaveAction = summary?.displayName != newName
|| summary?.topic != newTopic
|| summary?.canonicalAlias != newAlias
|| newHistoryVisibility != null
)
}
}
} }
private fun observeRoomSummary() { private fun observeRoomSummary() {
@ -67,13 +91,14 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
roomSummary = async, roomSummary = async,
newName = roomSummary?.displayName, newName = roomSummary?.displayName,
newTopic = roomSummary?.topic, newTopic = roomSummary?.topic,
newAlias = roomSummary?.canonicalAlias newCanonicalAlias = roomSummary?.canonicalAlias
) )
} }
val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable() val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable()
powerLevelsContentLive.subscribe { powerLevelsContentLive
.subscribe {
val powerLevelsHelper = PowerLevelsHelper(it) val powerLevelsHelper = PowerLevelsHelper(it)
val permissions = RoomSettingsViewState.ActionPermissions( val permissions = RoomSettingsViewState.ActionPermissions(
canChangeName = powerLevelsHelper.isUserAbleToChangeRoomName(session.myUserId), canChangeName = powerLevelsHelper.isUserAbleToChangeRoomName(session.myUserId),
@ -82,38 +107,19 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
canChangeHistoryReadability = powerLevelsHelper.isUserAbleToChangeRoomHistoryReadability(session.myUserId) canChangeHistoryReadability = powerLevelsHelper.isUserAbleToChangeRoomHistoryReadability(session.myUserId)
) )
setState { copy(actionPermissions = permissions) } setState { copy(actionPermissions = permissions) }
}.disposeOnClear() }
.disposeOnClear()
} }
override fun handle(action: RoomSettingsAction) { override fun handle(action: RoomSettingsAction) {
when (action) { when (action) {
is RoomSettingsAction.EnableEncryption -> handleEnableEncryption() is RoomSettingsAction.EnableEncryption -> handleEnableEncryption()
is RoomSettingsAction.SetRoomName -> { is RoomSettingsAction.SetRoomName -> setState { copy(newName = action.newName) }
setState { copy(newName = action.newName) } is RoomSettingsAction.SetRoomTopic -> setState { copy(newTopic = action.newTopic) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) } is RoomSettingsAction.SetRoomHistoryVisibility -> setState { copy(newHistoryVisibility = action.visibility) }
} is RoomSettingsAction.SetRoomAlias -> setState { copy(newCanonicalAlias = action.alias) }
is RoomSettingsAction.SetRoomTopic -> {
setState { copy(newTopic = action.newTopic) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) }
}
is RoomSettingsAction.SetRoomHistoryVisibility -> {
setState { copy(newHistoryVisibility = action.visibility) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) }
}
is RoomSettingsAction.SetRoomAlias -> {
setState { copy(newAlias = action.alias) }
setState { copy(showSaveAction = shouldShowSaveAction(this)) }
}
is RoomSettingsAction.Save -> saveSettings() is RoomSettingsAction.Save -> saveSettings()
} }.exhaustive
}
private fun shouldShowSaveAction(state: RoomSettingsViewState): Boolean {
val summary = state.roomSummary.invoke()
return summary?.displayName != state.newName
|| summary?.topic != state.newTopic
|| summary?.canonicalAlias != state.newAlias
|| state.newHistoryVisibility != null
} }
private fun saveSettings() = withState { state -> private fun saveSettings() = withState { state ->
@ -130,13 +136,13 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
operationList.add(room.rx().updateTopic(state.newTopic ?: "")) operationList.add(room.rx().updateTopic(state.newTopic ?: ""))
} }
if (state.newAlias != null && summary?.canonicalAlias != state.newAlias) { if (state.newCanonicalAlias != null && summary?.canonicalAlias != state.newCanonicalAlias.takeIf { it.isNotEmpty() }) {
operationList.add(room.rx().addRoomAlias(state.newAlias)) operationList.add(room.rx().addRoomAlias(state.newCanonicalAlias))
operationList.add(room.rx().updateCanonicalAlias(state.newAlias)) operationList.add(room.rx().updateCanonicalAlias(state.newCanonicalAlias))
} }
if (state.newHistoryVisibility != null) { if (state.newHistoryVisibility != null) {
operationList.add(room.rx().updateHistoryReadability(state.newHistoryVisibility.name.toLowerCase(Locale.ROOT))) operationList.add(room.rx().updateHistoryReadability(state.newHistoryVisibility))
} }
Observable Observable
@ -146,7 +152,6 @@ class RoomSettingsViewModel @AssistedInject constructor(@Assisted initialState:
{ {
postLoading(false) postLoading(false)
setState { copy(newHistoryVisibility = null) } setState { copy(newHistoryVisibility = null) }
setState { copy(showSaveAction = false) }
_viewEvents.post(RoomSettingsViewEvents.Success) _viewEvents.post(RoomSettingsViewEvents.Success)
}, },
{ {

View File

@ -32,7 +32,7 @@ data class RoomSettingsViewState(
val newName: String? = null, val newName: String? = null,
val newTopic: String? = null, val newTopic: String? = null,
val newHistoryVisibility: RoomHistoryVisibility? = null, val newHistoryVisibility: RoomHistoryVisibility? = null,
val newAlias: String? = null, val newCanonicalAlias: String? = null,
val showSaveAction: Boolean = false, val showSaveAction: Boolean = false,
val actionPermissions: ActionPermissions = ActionPermissions() val actionPermissions: ActionPermissions = ActionPermissions()
) : MvRxState { ) : MvRxState {

View File

@ -32,11 +32,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/layout_horizontal_margin" android:layout_marginEnd="@dimen/layout_horizontal_margin"
android:background="?attr/colorAccent"
app:layout_constraintBottom_toBottomOf="@id/formTextInputTextInputLayout" app:layout_constraintBottom_toBottomOf="@id/formTextInputTextInputLayout"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/formTextInputTextInputLayout" app:layout_constraintTop_toTopOf="@id/formTextInputTextInputLayout"
android:background="?attr/colorAccent" tools:text="Add" />
tools:text="Add"/>
<View <View
android:id="@+id/formTextInputDivider" android:id="@+id/formTextInputDivider"

View File

@ -3,9 +3,9 @@
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="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_attachment_type_selector"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:background="@drawable/bg_attachment_type_selector"
android:orientation="vertical" android:orientation="vertical"
android:paddingTop="16dp" android:paddingTop="16dp"
android:paddingBottom="16dp"> android:paddingBottom="16dp">
@ -28,9 +28,9 @@
<ImageButton <ImageButton
android:id="@+id/avatarCameraButton" android:id="@+id/avatarCameraButton"
style="@style/AttachmentTypeSelectorButton" style="@style/AttachmentTypeSelectorButton"
android:src="@drawable/ic_attachment_camera_white_24dp"
android:contentDescription="@string/attachment_type_camera" android:contentDescription="@string/attachment_type_camera"
tools:background="@color/colorAccent" /> android:src="@drawable/ic_attachment_camera_white_24dp"
tools:background="@color/riotx_accent" />
<TextView <TextView
style="@style/AttachmentTypeSelectorLabel" style="@style/AttachmentTypeSelectorLabel"
@ -50,9 +50,9 @@
<ImageButton <ImageButton
android:id="@+id/avatarGalleryButton" android:id="@+id/avatarGalleryButton"
style="@style/AttachmentTypeSelectorButton" style="@style/AttachmentTypeSelectorButton"
android:src="@drawable/ic_attachment_gallery_white_24dp"
android:contentDescription="@string/attachment_type_gallery" android:contentDescription="@string/attachment_type_gallery"
tools:background="@color/colorAccent" /> android:src="@drawable/ic_attachment_gallery_white_24dp"
tools:background="@color/riotx_accent" />
<TextView <TextView
style="@style/AttachmentTypeSelectorLabel" style="@style/AttachmentTypeSelectorLabel"