mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge branch 'develop' into feature/fix_reply_tag
This commit is contained in:
commit
a47ff99be7
@ -7,6 +7,8 @@ Features ✨:
|
||||
Improvements 🙌:
|
||||
- Sending events is now retried only 3 times, so we avoid blocking the sending queue too long.
|
||||
- Display warning when fail to send events in room list
|
||||
- Improve UI of edit role action in member profile
|
||||
- Moderation | New screen to display list of banned users in room settings, with unban action
|
||||
|
||||
Bugfix 🐛:
|
||||
- Fix theme issue on Room directory screen (#1613)
|
||||
@ -17,6 +19,9 @@ Bugfix 🐛:
|
||||
- Fix Infinite loop at startup when migrating account from Riot (#1699)
|
||||
- Fix Element crashes in loop after initial sync (#1709)
|
||||
- Remove inner mx-reply tags before replying
|
||||
- Fix timeline items not loading when there are only filtered events
|
||||
- Fix "Voice & Video" grayed out in Settings (#1733)
|
||||
- Fix Allow VOIP call in all rooms with 2 participants (even if not DM)
|
||||
|
||||
Translations 🗣:
|
||||
-
|
||||
|
@ -67,7 +67,7 @@ data class RoomSummary constructor(
|
||||
get() = tags.any { it.name == RoomTag.ROOM_TAG_FAVOURITE }
|
||||
|
||||
val canStartCall: Boolean
|
||||
get() = isDirect && joinedMembersCount == 2
|
||||
get() = joinedMembersCount == 2
|
||||
|
||||
companion object {
|
||||
const val NOT_IN_BREADCRUMBS = -1
|
||||
|
@ -169,7 +169,7 @@ internal class DefaultTimeline(
|
||||
filteredEvents = nonFilteredEvents.where()
|
||||
.filterEventsWithSettings()
|
||||
.findAll()
|
||||
filteredEvents.addChangeListener(eventsChangeListener)
|
||||
nonFilteredEvents.addChangeListener(eventsChangeListener)
|
||||
handleInitialLoad()
|
||||
if (settings.shouldHandleHiddenReadReceipts()) {
|
||||
hiddenReadReceipts.start(realm, filteredEvents, nonFilteredEvents, this)
|
||||
|
@ -77,6 +77,7 @@ import im.vector.riotx.features.roommemberprofile.RoomMemberProfileFragment
|
||||
import im.vector.riotx.features.roommemberprofile.devices.DeviceListFragment
|
||||
import im.vector.riotx.features.roommemberprofile.devices.DeviceTrustInfoActionFragment
|
||||
import im.vector.riotx.features.roomprofile.RoomProfileFragment
|
||||
import im.vector.riotx.features.roomprofile.banned.RoomBannedMemberListFragment
|
||||
import im.vector.riotx.features.roomprofile.members.RoomMemberListFragment
|
||||
import im.vector.riotx.features.roomprofile.settings.RoomSettingsFragment
|
||||
import im.vector.riotx.features.roomprofile.uploads.RoomUploadsFragment
|
||||
@ -534,4 +535,9 @@ interface FragmentModule {
|
||||
@IntoMap
|
||||
@FragmentKey(ContactsBookFragment::class)
|
||||
fun bindPhoneBookFragment(fragment: ContactsBookFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomBannedMemberListFragment::class)
|
||||
fun bindRoomBannedMemberListFragment(fragment: RoomBannedMemberListFragment): Fragment
|
||||
}
|
||||
|
@ -16,7 +16,9 @@
|
||||
|
||||
package im.vector.riotx.core.epoxy
|
||||
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
@ -26,14 +28,16 @@ import im.vector.riotx.core.extensions.setTextOrHide
|
||||
abstract class LoadingItem : VectorEpoxyModel<LoadingItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute var loadingText: String? = null
|
||||
@EpoxyAttribute var showLoader: Boolean = true
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
|
||||
holder.progressBar.isVisible = showLoader
|
||||
holder.textView.setTextOrHide(loadingText)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val textView by bind<TextView>(R.id.loadingText)
|
||||
val progressBar by bind<ProgressBar>(R.id.loadingProgress)
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.core.epoxy.profiles
|
||||
|
||||
import android.view.View
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.extensions.setTextOrHide
|
||||
import im.vector.riotx.features.crypto.util.toImageRes
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
|
||||
abstract class BaseProfileMatrixItem<T : ProfileMatrixItem.Holder> : VectorEpoxyModel<T>() {
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var editable: Boolean = true
|
||||
@EpoxyAttribute
|
||||
var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
||||
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||
|
||||
override fun bind(holder: T) {
|
||||
super.bind(holder)
|
||||
val bestName = matrixItem.getBestName()
|
||||
val matrixId = matrixItem.id
|
||||
.takeIf { it != bestName }
|
||||
// Special case for ThreePid fake matrix item
|
||||
.takeIf { it != "@" }
|
||||
holder.view.setOnClickListener(clickListener?.takeIf { editable })
|
||||
holder.titleView.text = bestName
|
||||
holder.subtitleView.setTextOrHide(matrixId)
|
||||
holder.editableView.isVisible = editable
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
holder.avatarDecorationImageView.setImageResource(userEncryptionTrustLevel.toImageRes())
|
||||
}
|
||||
}
|
@ -20,43 +20,14 @@ package im.vector.riotx.core.epoxy.profiles
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.matrix.android.api.crypto.RoomEncryptionTrustLevel
|
||||
import im.vector.matrix.android.api.util.MatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotx.core.extensions.setTextOrHide
|
||||
import im.vector.riotx.features.crypto.util.toImageRes
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_profile_matrix_item)
|
||||
abstract class ProfileMatrixItem : VectorEpoxyModel<ProfileMatrixItem.Holder>() {
|
||||
abstract class ProfileMatrixItem : BaseProfileMatrixItem<ProfileMatrixItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var editable: Boolean = true
|
||||
@EpoxyAttribute var userEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
||||
@EpoxyAttribute var clickListener: View.OnClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
val bestName = matrixItem.getBestName()
|
||||
val matrixId = matrixItem.id
|
||||
.takeIf { it != bestName }
|
||||
// Special case for ThreePid fake matrix item
|
||||
.takeIf { it != "@" }
|
||||
holder.view.setOnClickListener(clickListener?.takeIf { editable })
|
||||
holder.titleView.text = bestName
|
||||
holder.subtitleView.setTextOrHide(matrixId)
|
||||
holder.editableView.isVisible = editable
|
||||
avatarRenderer.render(matrixItem, holder.avatarImageView)
|
||||
holder.avatarDecorationImageView.setImageResource(userEncryptionTrustLevel.toImageRes())
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
open class Holder : VectorEpoxyHolder() {
|
||||
val titleView by bind<TextView>(R.id.matrixItemTitle)
|
||||
val subtitleView by bind<TextView>(R.id.matrixItemSubtitle)
|
||||
val avatarImageView by bind<ImageView>(R.id.matrixItemAvatar)
|
||||
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2020 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.riotx.core.epoxy.profiles
|
||||
|
||||
import android.widget.ProgressBar
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_profile_matrix_item_progress)
|
||||
abstract class ProfileMatrixItemWithProgress : BaseProfileMatrixItem<ProfileMatrixItemWithProgress.Holder>() {
|
||||
|
||||
@EpoxyAttribute var inProgress: Boolean = true
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.progress.isVisible = inProgress
|
||||
}
|
||||
|
||||
class Holder : ProfileMatrixItem.Holder() {
|
||||
val progress by bind<ProgressBar>(R.id.matrixItemProgress)
|
||||
}
|
||||
}
|
@ -74,7 +74,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||
fun onEncryptedMessageClicked(informationData: MessageInformationData, view: View)
|
||||
fun onImageMessageClicked(messageImageContent: MessageImageInfoContent, mediaData: ImageContentRenderer.Data, view: View)
|
||||
fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View)
|
||||
// fun onFileMessageClicked(eventId: String, messageFileContent: MessageFileContent)
|
||||
|
||||
// fun onFileMessageClicked(eventId: String, messageFileContent: MessageFileContent)
|
||||
// fun onAudioMessageClicked(messageAudioContent: MessageAudioContent)
|
||||
fun onEditedDecorationClicked(informationData: MessageInformationData)
|
||||
|
||||
@ -107,7 +108,6 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||
fun onUrlLongClicked(url: String): Boolean
|
||||
}
|
||||
|
||||
private var showingForwardLoader = false
|
||||
// Map eventId to adapter position
|
||||
private val adapterPositionMapping = HashMap<String, Int>()
|
||||
private val modelCache = arrayListOf<CacheItemData?>()
|
||||
@ -233,7 +233,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||
|
||||
override fun buildModels() {
|
||||
val timestamp = System.currentTimeMillis()
|
||||
showingForwardLoader = LoadingItem_()
|
||||
|
||||
val showingForwardLoader = LoadingItem_()
|
||||
.id("forward_loading_item_$timestamp")
|
||||
.setVisibilityStateChangedListener(Timeline.Direction.FORWARDS)
|
||||
.addWhenLoading(Timeline.Direction.FORWARDS)
|
||||
@ -242,12 +243,13 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||
add(timelineModels)
|
||||
|
||||
// Avoid displaying two loaders if there is no elements between them
|
||||
if (!showingForwardLoader || timelineModels.isNotEmpty()) {
|
||||
LoadingItem_()
|
||||
.id("backward_loading_item_$timestamp")
|
||||
.setVisibilityStateChangedListener(Timeline.Direction.BACKWARDS)
|
||||
.addWhenLoading(Timeline.Direction.BACKWARDS)
|
||||
}
|
||||
val showBackwardsLoader = !showingForwardLoader || timelineModels.isNotEmpty()
|
||||
// We can hide the loader but still add the item to controller so it can trigger backwards pagination
|
||||
LoadingItem_()
|
||||
.id("backward_loading_item_$timestamp")
|
||||
.setVisibilityStateChangedListener(Timeline.Direction.BACKWARDS)
|
||||
.showLoader(showBackwardsLoader)
|
||||
.addWhenLoading(Timeline.Direction.BACKWARDS)
|
||||
}
|
||||
|
||||
// Timeline.LISTENER ***************************************************************************
|
||||
|
@ -19,12 +19,10 @@ package im.vector.riotx.features.login
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
@ -73,14 +71,6 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
get() = supportFragmentManager.findFragmentById(R.id.loginFragmentContainer)
|
||||
|
||||
private val commonOption: (FragmentTransaction) -> Unit = { ft ->
|
||||
// Find the loginLogo on the current Fragment, this should not return null
|
||||
(topFragment?.view as? ViewGroup)
|
||||
// Find findViewById does not work, I do not know why
|
||||
// findViewById<View?>(R.id.loginLogo)
|
||||
?.children
|
||||
?.firstOrNull { it.id == R.id.loginLogo }
|
||||
?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
// TODO
|
||||
ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
|
||||
}
|
||||
|
||||
@ -145,7 +135,6 @@ open class LoginActivity : VectorBaseActivity(), ToolbarConfigurable {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
LoginServerSelectionFragment::class.java,
|
||||
option = { ft ->
|
||||
findViewById<View?>(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
findViewById<View?>(R.id.loginSplashTitle)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
findViewById<View?>(R.id.loginSplashSubmit)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
// TODO Disabled because it provokes a flickering
|
||||
|
@ -236,10 +236,12 @@ class RoomMemberProfileController @Inject constructor(
|
||||
if (canEditPowerLevel) {
|
||||
buildProfileAction(
|
||||
id = "edit_power_level",
|
||||
editable = false,
|
||||
title = powerLevelsStr,
|
||||
editable = true,
|
||||
title = stringProvider.getString(R.string.power_level_title),
|
||||
subtitle = powerLevelsStr,
|
||||
divider = canKick || canBan,
|
||||
dividerColor = dividerColor,
|
||||
editableRes = R.drawable.ic_edit,
|
||||
action = { callback?.onEditPowerLevel(userPowerLevel) }
|
||||
)
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewEvents
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewModel
|
||||
import im.vector.riotx.features.room.RequireActiveMembershipViewState
|
||||
import im.vector.riotx.features.roomprofile.banned.RoomBannedMemberListFragment
|
||||
import im.vector.riotx.features.roomprofile.members.RoomMemberListFragment
|
||||
import im.vector.riotx.features.roomprofile.settings.RoomSettingsFragment
|
||||
import im.vector.riotx.features.roomprofile.uploads.RoomUploadsFragment
|
||||
@ -81,9 +82,10 @@ class RoomProfileActivity :
|
||||
.observe()
|
||||
.subscribe { sharedAction ->
|
||||
when (sharedAction) {
|
||||
is RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
||||
is RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
||||
is RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
||||
is RoomProfileSharedAction.OpenRoomMembers -> openRoomMembers()
|
||||
is RoomProfileSharedAction.OpenRoomSettings -> openRoomSettings()
|
||||
is RoomProfileSharedAction.OpenRoomUploads -> openRoomUploads()
|
||||
is RoomProfileSharedAction.OpenBannedRoomMembers -> openBannedRoomMembers()
|
||||
}
|
||||
}
|
||||
.disposeOnDestroy()
|
||||
@ -114,6 +116,10 @@ class RoomProfileActivity :
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openBannedRoomMembers() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomBannedMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
override fun configure(toolbar: Toolbar) {
|
||||
configureToolbar(toolbar)
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ class RoomProfileController @Inject constructor(
|
||||
interface Callback {
|
||||
fun onLearnMoreClicked()
|
||||
fun onMemberListClicked()
|
||||
fun onBannedMemberListClicked()
|
||||
fun onNotificationsClicked()
|
||||
fun onUploadsClicked()
|
||||
fun onSettingsClicked()
|
||||
@ -92,6 +93,16 @@ class RoomProfileController @Inject constructor(
|
||||
accessory = R.drawable.ic_shield_warning.takeIf { hasWarning } ?: 0,
|
||||
action = { callback?.onMemberListClicked() }
|
||||
)
|
||||
|
||||
if (data.bannedMembership.invoke()?.isNotEmpty() == true) {
|
||||
buildProfileAction(
|
||||
id = "banned_list",
|
||||
title = stringProvider.getString(R.string.room_settings_banned_users_title),
|
||||
dividerColor = dividerColor,
|
||||
icon = R.drawable.ic_settings_root_labs,
|
||||
action = { callback?.onBannedMemberListClicked() }
|
||||
)
|
||||
}
|
||||
buildProfileAction(
|
||||
id = "uploads",
|
||||
title = stringProvider.getString(R.string.room_profile_section_more_uploads),
|
||||
|
@ -206,6 +206,10 @@ class RoomProfileFragment @Inject constructor(
|
||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomMembers)
|
||||
}
|
||||
|
||||
override fun onBannedMemberListClicked() {
|
||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenBannedRoomMembers)
|
||||
}
|
||||
|
||||
override fun onSettingsClicked() {
|
||||
roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomSettings)
|
||||
}
|
||||
|
@ -25,4 +25,5 @@ sealed class RoomProfileSharedAction : VectorSharedAction {
|
||||
object OpenRoomSettings : RoomProfileSharedAction()
|
||||
object OpenRoomUploads : RoomProfileSharedAction()
|
||||
object OpenRoomMembers : RoomProfileSharedAction()
|
||||
object OpenBannedRoomMembers : RoomProfileSharedAction()
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ import im.vector.matrix.android.api.MatrixCallback
|
||||
import im.vector.matrix.android.api.permalinks.PermalinkFactory
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.room.members.roomMemberQueryParams
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.matrix.rx.unwrap
|
||||
@ -61,7 +63,8 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
val rxRoom = room.rx()
|
||||
rxRoom.liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute {
|
||||
copy(roomSummary = it)
|
||||
@ -73,10 +76,17 @@ class RoomProfileViewModel @AssistedInject constructor(@Assisted private val ini
|
||||
.subscribe {
|
||||
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||
setState {
|
||||
copy(canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR))
|
||||
copy(canChangeAvatar = powerLevelsHelper.isUserAllowedToSend(session.myUserId, true, EventType.STATE_ROOM_AVATAR))
|
||||
}
|
||||
}
|
||||
.disposeOnClear()
|
||||
|
||||
rxRoom.liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
|
||||
.execute {
|
||||
copy(
|
||||
bannedMembership = it
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: RoomProfileAction) = when (action) {
|
||||
|
@ -20,11 +20,13 @@ package im.vector.riotx.features.roomprofile
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
|
||||
data class RoomProfileViewState(
|
||||
val roomId: String,
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val bannedMembership: Async<List<RoomMemberSummary>> = Uninitialized,
|
||||
val canChangeAvatar: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.riotx.core.platform.VectorViewModelAction
|
||||
|
||||
sealed class RoomBannedListMemberAction : VectorViewModelAction {
|
||||
data class QueryInfo(val roomMemberSummary: RoomMemberSummary) : RoomBannedListMemberAction()
|
||||
data class UnBanUser(val roomMemberSummary: RoomMemberSummary) : RoomBannedListMemberAction()
|
||||
}
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.query.QueryStringValue
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.members.roomMemberQueryParams
|
||||
import im.vector.matrix.android.api.session.room.model.Membership
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberContent
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.matrix.android.api.session.room.powerlevels.PowerLevelsHelper
|
||||
import im.vector.matrix.android.internal.util.awaitCallback
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.matrix.rx.unwrap
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.powerlevel.PowerLevelsObservableFactory
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RoomBannedListMemberViewModel @AssistedInject constructor(@Assisted initialState: RoomBannedMemberListViewState,
|
||||
private val stringProvider: StringProvider,
|
||||
private val session: Session)
|
||||
: VectorViewModel<RoomBannedMemberListViewState, RoomBannedListMemberAction, RoomBannedViewEvents>(initialState) {
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: RoomBannedMemberListViewState): RoomBannedListMemberViewModel
|
||||
}
|
||||
|
||||
private val room = session.getRoom(initialState.roomId)!!
|
||||
|
||||
init {
|
||||
val rxRoom = room.rx()
|
||||
|
||||
room.rx().liveRoomSummary()
|
||||
.unwrap()
|
||||
.execute { async ->
|
||||
copy(roomSummary = async)
|
||||
}
|
||||
|
||||
rxRoom.liveRoomMembers(roomMemberQueryParams { memberships = listOf(Membership.BAN) })
|
||||
.execute {
|
||||
copy(
|
||||
bannedMemberSummaries = it
|
||||
)
|
||||
}
|
||||
|
||||
val powerLevelsContentLive = PowerLevelsObservableFactory(room).createObservable()
|
||||
|
||||
powerLevelsContentLive.subscribe {
|
||||
val powerLevelsHelper = PowerLevelsHelper(it)
|
||||
setState { copy(canUserBan = powerLevelsHelper.isUserAbleToBan(session.myUserId)) }
|
||||
}.disposeOnClear()
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<RoomBannedListMemberViewModel, RoomBannedMemberListViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: RoomBannedMemberListViewState): RoomBannedListMemberViewModel? {
|
||||
val fragment: RoomBannedMemberListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return fragment.viewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: RoomBannedListMemberAction) {
|
||||
when (action) {
|
||||
is RoomBannedListMemberAction.QueryInfo -> onQueryBanInfo(action.roomMemberSummary)
|
||||
is RoomBannedListMemberAction.UnBanUser -> unBanUser(action.roomMemberSummary)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onQueryBanInfo(roomMemberSummary: RoomMemberSummary) {
|
||||
val bannedEvent = room.getStateEvent(EventType.STATE_ROOM_MEMBER, QueryStringValue.Equals(roomMemberSummary.userId))
|
||||
val content = bannedEvent?.getClearContent().toModel<RoomMemberContent>()
|
||||
if (content?.membership != Membership.BAN) {
|
||||
// may be report error?
|
||||
return
|
||||
}
|
||||
|
||||
val reason = content.reason
|
||||
val bannedBy = bannedEvent?.senderId ?: return
|
||||
|
||||
_viewEvents.post(RoomBannedViewEvents.ShowBannedInfo(bannedBy, reason ?: "", roomMemberSummary))
|
||||
}
|
||||
|
||||
private fun unBanUser(roomMemberSummary: RoomMemberSummary) {
|
||||
setState {
|
||||
copy(onGoingModerationAction = this.onGoingModerationAction + roomMemberSummary.userId)
|
||||
}
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
awaitCallback<Unit> {
|
||||
room.unban(roomMemberSummary.userId, null, it)
|
||||
}
|
||||
} catch (failure: Throwable) {
|
||||
_viewEvents.post(RoomBannedViewEvents.ToastError(stringProvider.getString(R.string.failed_to_unban)))
|
||||
} finally {
|
||||
setState {
|
||||
copy(
|
||||
onGoingModerationAction = onGoingModerationAction - roomMemberSummary.userId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.dividerItem
|
||||
import im.vector.riotx.core.epoxy.profiles.buildProfileSection
|
||||
import im.vector.riotx.core.epoxy.profiles.profileMatrixItemWithProgress
|
||||
import im.vector.riotx.core.extensions.join
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.core.ui.list.genericFooterItem
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomBannedMemberListController @Inject constructor(
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val stringProvider: StringProvider,
|
||||
colorProvider: ColorProvider
|
||||
) : TypedEpoxyController<RoomBannedMemberListViewState>() {
|
||||
|
||||
interface Callback {
|
||||
fun onUnbanClicked(roomMember: RoomMemberSummary)
|
||||
}
|
||||
|
||||
private val dividerColor = colorProvider.getColorFromAttribute(R.attr.vctr_list_divider_color)
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
init {
|
||||
setData(null)
|
||||
}
|
||||
|
||||
override fun buildModels(data: RoomBannedMemberListViewState?) {
|
||||
val bannedList = data?.bannedMemberSummaries?.invoke() ?: return
|
||||
|
||||
buildProfileSection(
|
||||
stringProvider.getString(R.string.room_settings_banned_users_title)
|
||||
)
|
||||
|
||||
bannedList.join(
|
||||
each = { _, roomMember ->
|
||||
val actionInProgress = data.onGoingModerationAction.contains(roomMember.userId)
|
||||
profileMatrixItemWithProgress {
|
||||
id(roomMember.userId)
|
||||
matrixItem(roomMember.toMatrixItem())
|
||||
avatarRenderer(avatarRenderer)
|
||||
apply {
|
||||
if (actionInProgress) {
|
||||
inProgress(true)
|
||||
editable(false)
|
||||
} else {
|
||||
inProgress(false)
|
||||
editable(true)
|
||||
clickListener { _ ->
|
||||
callback?.onUnbanClicked(roomMember)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
between = { _, roomMemberBefore ->
|
||||
dividerItem {
|
||||
id("divider_${roomMemberBefore.userId}")
|
||||
color(dividerColor)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
genericFooterItem {
|
||||
id("footer")
|
||||
text(stringProvider.getQuantityString(R.plurals.room_settings_banned_users_count, bannedList.size, bannedList.size))
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.airbnb.mvrx.args
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.matrix.android.api.util.toMatrixItem
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.cleanup
|
||||
import im.vector.riotx.core.extensions.configureWith
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.utils.toast
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.roomprofile.RoomProfileArgs
|
||||
import kotlinx.android.synthetic.main.fragment_room_setting_generic.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomBannedMemberListFragment @Inject constructor(
|
||||
val viewModelFactory: RoomBannedListMemberViewModel.Factory,
|
||||
private val roomMemberListController: RoomBannedMemberListController,
|
||||
private val avatarRenderer: AvatarRenderer
|
||||
) : VectorBaseFragment(), RoomBannedMemberListController.Callback {
|
||||
|
||||
private val viewModel: RoomBannedListMemberViewModel by fragmentViewModel()
|
||||
private val roomProfileArgs: RoomProfileArgs by args()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_room_setting_generic
|
||||
|
||||
override fun onUnbanClicked(roomMember: RoomMemberSummary) {
|
||||
viewModel.handle(RoomBannedListMemberAction.QueryInfo(roomMember))
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
roomMemberListController.callback = this
|
||||
setupToolbar(roomSettingsToolbar)
|
||||
recyclerView.configureWith(roomMemberListController, hasFixedSize = true)
|
||||
|
||||
viewModel.observeViewEvents {
|
||||
when (it) {
|
||||
is RoomBannedViewEvents.ShowBannedInfo -> {
|
||||
val canBan = withState(viewModel) { state -> state.canUserBan }
|
||||
AlertDialog.Builder(requireActivity())
|
||||
.setTitle(getString(R.string.member_banned_by, it.bannedByUserId))
|
||||
.setMessage(getString(R.string.reason_colon, it.banReason))
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.apply {
|
||||
if (canBan) {
|
||||
setNegativeButton(R.string.room_participants_action_unban) { _, _ ->
|
||||
viewModel.handle(RoomBannedListMemberAction.UnBanUser(it.roomMemberSummary))
|
||||
}
|
||||
}
|
||||
}
|
||||
.show()
|
||||
}
|
||||
is RoomBannedViewEvents.ToastError -> {
|
||||
requireActivity().toast(it.info)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
recyclerView.cleanup()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) { viewState ->
|
||||
roomMemberListController.setData(viewState)
|
||||
renderRoomSummary(viewState)
|
||||
}
|
||||
|
||||
private fun renderRoomSummary(state: RoomBannedMemberListViewState) {
|
||||
state.roomSummary()?.let {
|
||||
roomSettingsToolbarTitleView.text = it.displayName
|
||||
avatarRenderer.render(it.toMatrixItem(), roomSettingsToolbarAvatarImageView)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||
import im.vector.riotx.features.roomprofile.RoomProfileArgs
|
||||
|
||||
data class RoomBannedMemberListViewState(
|
||||
val roomId: String,
|
||||
val roomSummary: Async<RoomSummary> = Uninitialized,
|
||||
val bannedMemberSummaries: Async<List<RoomMemberSummary>> = Uninitialized,
|
||||
val onGoingModerationAction: List<String> = emptyList(),
|
||||
val canUserBan: Boolean = false
|
||||
) : MvRxState {
|
||||
|
||||
constructor(args: RoomProfileArgs) : this(roomId = args.roomId)
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.riotx.features.roomprofile.banned
|
||||
|
||||
import im.vector.matrix.android.api.session.room.model.RoomMemberSummary
|
||||
import im.vector.riotx.core.platform.VectorViewEvents
|
||||
|
||||
sealed class RoomBannedViewEvents : VectorViewEvents {
|
||||
data class ShowBannedInfo(val bannedByUserId: String, val banReason: String, val roomMemberSummary: RoomMemberSummary) : RoomBannedViewEvents()
|
||||
data class ToastError(val info: String) : RoomBannedViewEvents()
|
||||
}
|
@ -28,7 +28,6 @@ import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.login.LoginMode
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginCenterButtonItem
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginErrorWithRetryItem
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginHeaderItem
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginPasswordFormItem
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginRedButtonItem
|
||||
import im.vector.riotx.features.signout.soft.epoxy.loginTextItem
|
||||
@ -65,9 +64,6 @@ class SoftLogoutController @Inject constructor(
|
||||
}
|
||||
|
||||
private fun buildHeader(state: SoftLogoutViewState) {
|
||||
loginHeaderItem {
|
||||
id("header")
|
||||
}
|
||||
loginTitleItem {
|
||||
id("title")
|
||||
text(stringProvider.getString(R.string.soft_logout_title))
|
||||
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* 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.riotx.features.signout.soft.epoxy
|
||||
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotx.core.epoxy.VectorEpoxyModel
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_login_header)
|
||||
abstract class LoginHeaderItem : VectorEpoxyModel<LoginHeaderItem.Holder>() {
|
||||
class Holder : VectorEpoxyHolder()
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="155dp"
|
||||
android:height="33dp"
|
||||
android:viewportWidth="155"
|
||||
android:viewportHeight="33">
|
||||
<path
|
||||
android:pathData="M21.533,22.855H4.969C5.165,24.595 5.794,25.985 6.856,27.023C7.918,28.034 9.316,28.539 11.05,28.539C12.196,28.539 13.23,28.258 14.153,27.697C15.075,27.135 15.732,26.378 16.124,25.423H21.156C20.485,27.641 19.227,29.437 17.382,30.812C15.564,32.16 13.412,32.833 10.924,32.833C7.681,32.833 5.053,31.753 3.04,29.591C1.055,27.43 0.063,24.694 0.063,21.381C0.063,18.153 1.069,15.445 3.082,13.255C5.095,11.066 7.695,9.972 10.882,9.972C14.069,9.972 16.641,11.052 18.598,13.213C20.583,15.347 21.575,18.041 21.575,21.297L21.533,22.855ZM10.882,14.056C9.316,14.056 8.016,14.519 6.982,15.445C5.947,16.371 5.304,17.606 5.053,19.15H16.627C16.403,17.606 15.788,16.371 14.782,15.445C13.775,14.519 12.475,14.056 10.882,14.056Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M25.009,25.802V0.751H30V25.886C30,27.009 30.615,27.57 31.845,27.57L32.725,27.528V32.286C32.25,32.37 31.747,32.412 31.216,32.412C29.063,32.412 27.483,31.865 26.477,30.77C25.499,29.676 25.009,28.02 25.009,25.802Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M55.966,22.855H39.401C39.597,24.595 40.226,25.985 41.289,27.023C42.351,28.034 43.749,28.539 45.482,28.539C46.628,28.539 47.663,28.258 48.585,27.697C49.508,27.135 50.165,26.378 50.556,25.423H55.588C54.917,27.641 53.659,29.437 51.814,30.812C49.997,32.16 47.844,32.833 45.356,32.833C42.113,32.833 39.485,31.753 37.472,29.591C35.487,27.43 34.495,24.694 34.495,21.381C34.495,18.153 35.501,15.445 37.514,13.255C39.527,11.066 42.127,9.972 45.314,9.972C48.501,9.972 51.073,11.052 53.03,13.213C55.015,15.347 56.008,18.041 56.008,21.297L55.966,22.855ZM45.314,14.056C43.749,14.056 42.449,14.519 41.414,15.445C40.38,16.371 39.737,17.606 39.485,19.15H51.059C50.836,17.606 50.221,16.371 49.214,15.445C48.208,14.519 46.908,14.056 45.314,14.056Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M78.48,19.781V32.328H73.49V19.234C73.49,15.922 72.12,14.266 69.38,14.266C67.899,14.266 66.711,14.743 65.816,15.698C64.949,16.652 64.516,17.957 64.516,19.613V32.328H59.526V10.477H64.138V13.382C64.67,12.399 65.48,11.585 66.571,10.94C67.661,10.294 69.017,9.972 70.638,9.972C73.658,9.972 75.838,11.122 77.18,13.424C79.025,11.122 81.486,9.972 84.561,9.972C87.105,9.972 89.062,10.771 90.432,12.371C91.802,13.943 92.487,16.02 92.487,18.603V32.328H87.496V19.234C87.496,15.922 86.126,14.266 83.387,14.266C81.877,14.266 80.675,14.757 79.78,15.74C78.914,16.694 78.48,18.041 78.48,19.781Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M117.304,22.855H100.739C100.935,24.595 101.564,25.985 102.627,27.023C103.689,28.034 105.087,28.539 106.82,28.539C107.966,28.539 109.001,28.258 109.923,27.697C110.846,27.135 111.503,26.378 111.894,25.423H116.926C116.255,27.641 114.997,29.437 113.152,30.812C111.335,32.16 109.182,32.833 106.694,32.833C103.451,32.833 100.823,31.753 98.811,29.591C96.826,27.43 95.833,24.694 95.833,21.381C95.833,18.153 96.84,15.445 98.852,13.255C100.865,11.066 103.465,9.972 106.652,9.972C109.839,9.972 112.411,11.052 114.368,13.213C116.353,15.347 117.346,18.041 117.346,21.297L117.304,22.855ZM106.652,14.056C105.087,14.056 103.787,14.519 102.752,15.445C101.718,16.371 101.075,17.606 100.823,19.15H112.397C112.174,17.606 111.559,16.371 110.552,15.445C109.546,14.519 108.246,14.056 106.652,14.056Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M125.477,10.477V13.382C125.98,12.427 126.804,11.628 127.951,10.982C129.125,10.308 130.537,9.972 132.186,9.972C134.758,9.972 136.743,10.757 138.141,12.329C139.567,13.901 140.28,15.992 140.28,18.603V32.328H135.289V19.234C135.289,17.69 134.926,16.483 134.199,15.613C133.5,14.715 132.424,14.266 130.97,14.266C129.376,14.266 128.118,14.743 127.196,15.698C126.301,16.652 125.854,17.971 125.854,19.655V32.328H120.864V10.477H125.477Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M154.854,27.865V32.202C154.239,32.37 153.372,32.454 152.254,32.454C148.004,32.454 145.88,30.307 145.88,26.013V14.476H142.567V10.477H145.88V4.793H150.87V10.477H154.938V14.476H150.87V25.507C150.87,27.22 151.681,28.076 153.302,28.076L154.854,27.865Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
43
vector/src/main/res/drawable/element_logotype_combined.xml
Normal file
43
vector/src/main/res/drawable/element_logotype_combined.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="369dp"
|
||||
android:height="211dp"
|
||||
android:viewportWidth="369"
|
||||
android:viewportHeight="211">
|
||||
<path
|
||||
android:pathData="M51.155,186.5H11.69C12.156,190.633 13.655,193.933 16.186,196.4C18.717,198.8 22.047,200 26.177,200C28.908,200 31.373,199.333 33.571,198C35.769,196.667 37.334,194.867 38.267,192.6H50.256C48.658,197.867 45.66,202.133 41.264,205.4C36.934,208.6 31.806,210.2 25.877,210.2C18.151,210.2 11.89,207.633 7.094,202.5C2.365,197.367 0,190.867 0,183C0,175.333 2.398,168.9 7.194,163.7C11.99,158.5 18.184,155.9 25.778,155.9C33.371,155.9 39.499,158.467 44.161,163.6C48.891,168.667 51.255,175.067 51.255,182.8L51.155,186.5ZM25.778,165.6C22.047,165.6 18.95,166.7 16.486,168.9C14.021,171.1 12.489,174.033 11.89,177.7H39.466C38.933,174.033 37.467,171.1 35.069,168.9C32.672,166.7 29.574,165.6 25.778,165.6Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M59.437,193.5V134H71.327V193.7C71.327,196.367 72.792,197.7 75.723,197.7L77.821,197.6V208.9C76.689,209.1 75.49,209.2 74.224,209.2C69.095,209.2 65.332,207.9 62.934,205.3C60.603,202.7 59.437,198.767 59.437,193.5Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M133.193,186.5H93.728C94.194,190.633 95.693,193.933 98.224,196.4C100.755,198.8 104.085,200 108.215,200C110.946,200 113.41,199.333 115.609,198C117.807,196.667 119.372,194.867 120.304,192.6H132.294C130.695,197.867 127.698,202.133 123.302,205.4C118.972,208.6 113.843,210.2 107.915,210.2C100.189,210.2 93.927,207.633 89.132,202.5C84.402,197.367 82.038,190.867 82.038,183C82.038,175.333 84.436,168.9 89.231,163.7C94.027,158.5 100.222,155.9 107.815,155.9C115.409,155.9 121.537,158.467 126.199,163.6C130.928,168.667 133.293,175.067 133.293,182.8L133.193,186.5ZM107.815,165.6C104.085,165.6 100.988,166.7 98.523,168.9C96.059,171.1 94.527,174.033 93.927,177.7H121.503C120.971,174.033 119.505,171.1 117.107,168.9C114.709,166.7 111.612,165.6 107.815,165.6Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M186.835,179.2V209H174.946V177.9C174.946,170.033 171.682,166.1 165.154,166.1C161.624,166.1 158.793,167.233 156.662,169.5C154.597,171.767 153.564,174.867 153.564,178.8V209H141.675V157.1H152.665V164C153.931,161.667 155.862,159.733 158.46,158.2C161.058,156.667 164.288,155.9 168.152,155.9C175.345,155.9 180.541,158.633 183.738,164.1C188.134,158.633 193.996,155.9 201.323,155.9C207.384,155.9 212.047,157.8 215.311,161.6C218.574,165.333 220.206,170.267 220.206,176.4V209H208.317V177.9C208.317,170.033 205.053,166.1 198.525,166.1C194.928,166.1 192.064,167.267 189.933,169.6C187.868,171.867 186.835,175.067 186.835,179.2Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M279.335,186.5H239.87C240.336,190.633 241.835,193.933 244.366,196.4C246.897,198.8 250.227,200 254.357,200C257.088,200 259.552,199.333 261.751,198C263.949,196.667 265.514,194.867 266.447,192.6H278.436C276.837,197.867 273.84,202.133 269.444,205.4C265.114,208.6 259.985,210.2 254.057,210.2C246.331,210.2 240.069,207.633 235.274,202.5C230.544,197.367 228.18,190.867 228.18,183C228.18,175.333 230.578,168.9 235.374,163.7C240.169,158.5 246.364,155.9 253.957,155.9C261.551,155.9 267.679,158.467 272.341,163.6C277.071,168.667 279.435,175.067 279.435,182.8L279.335,186.5ZM253.957,165.6C250.227,165.6 247.13,166.7 244.665,168.9C242.201,171.1 240.669,174.033 240.069,177.7H267.645C267.113,174.033 265.647,171.1 263.249,168.9C260.851,166.7 257.754,165.6 253.957,165.6Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M298.807,157.1V164C300.006,161.733 301.971,159.833 304.702,158.3C307.5,156.7 310.863,155.9 314.793,155.9C320.921,155.9 325.651,157.767 328.981,161.5C332.378,165.233 334.077,170.2 334.077,176.4V209H322.187V177.9C322.187,174.233 321.321,171.367 319.589,169.3C317.924,167.167 315.36,166.1 311.896,166.1C308.099,166.1 305.102,167.233 302.904,169.5C300.772,171.767 299.707,174.9 299.707,178.9V209H287.817V157.1H298.807Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M368.8,198.4V208.7C367.335,209.1 365.27,209.3 362.606,209.3C352.481,209.3 347.419,204.2 347.419,194V166.6H339.526V157.1H347.419V143.6H359.308V157.1H369V166.6H359.308V192.8C359.308,196.867 361.24,198.9 365.103,198.9L368.8,198.4Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M171,6C171,2.686 173.686,0 177,0C199.091,0 217,17.909 217,40C217,43.314 214.314,46 211,46C207.686,46 205,43.314 205,40C205,24.536 192.464,12 177,12C173.686,12 171,9.314 171,6Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M199,94C199,97.314 196.314,100 193,100C170.909,100 153,82.091 153,60C153,56.686 155.686,54 159,54C162.314,54 165,56.686 165,60C165,75.464 177.536,88 193,88C196.314,88 199,90.686 199,94Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M141,64C137.686,64 135,61.314 135,58C135,35.909 152.909,18 175,18C178.314,18 181,20.686 181,24C181,27.314 178.314,30 175,30C159.536,30 147,42.536 147,58C147,61.314 144.314,64 141,64Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M229,36C232.314,36 235,38.686 235,42C235,64.091 217.091,82 195,82C191.686,82 189,79.314 189,76C189,72.686 191.686,70 195,70C210.464,70 223,57.464 223,42C223,38.686 225.686,36 229,36Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
@ -1,22 +1,20 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="21dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="21"
|
||||
android:viewportHeight="22">
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M9.4969,3.0606L2.8882,3.0606C1.8454,3.0606 1,3.9289 1,5L1,18.5758C1,19.6469 1.8454,20.5152 2.8882,20.5152L16.1056,20.5152C17.1484,20.5152 17.9938,19.6469 17.9938,18.5758L17.9938,11.7879"
|
||||
android:pathData="M4,18.6666L20,18.6666"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#9E9E9E"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
<path
|
||||
android:pathData="M16.5776,1.6061C17.3598,0.8027 18.6278,0.8027 19.4099,1.6061C20.1921,2.4094 20.1921,3.7118 19.4099,4.5152L10.441,13.7273L6.6646,14.697L7.6087,10.8182L16.5776,1.6061Z"
|
||||
android:pathData="M6.6667,14L16.0001,4.6666"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#9E9E9E"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#000000"
|
||||
android:strokeLineCap="round"/>
|
||||
</vector>
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -7,11 +7,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<!-- No scroll view in the screen, but use the style -->
|
||||
<LinearLayout
|
||||
|
@ -7,11 +7,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -5,11 +5,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -5,11 +5,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints,UnusedAttribute" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -7,11 +7,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -18,28 +18,17 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/loginSplashLogo"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:src="@drawable/element_logo_green"
|
||||
android:transitionName="loginLogoTransition"
|
||||
app:layout_constraintBottom_toTopOf="@+id/logoType"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/logoType"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="44dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:src="@drawable/element_logotype"
|
||||
android:layout_height="102dp"
|
||||
android:src="@drawable/element_logotype_combined"
|
||||
android:tint="?colorAccent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/loginSplashLogo" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loginSplashTitle"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -6,11 +6,6 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="?riotx_background">
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<ImageView
|
||||
style="@style/LoginLogo"
|
||||
tools:ignore="ContentDescription,MissingConstraints" />
|
||||
|
||||
<!-- Missing attributes are in the style -->
|
||||
<androidx.core.widget.NestedScrollView
|
||||
style="@style/LoginFormScrollView"
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="1dp"
|
||||
android:background="?riotx_background"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@id/loginLogo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="32dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/element_logo_green" />
|
102
vector/src/main/res/layout/item_profile_matrix_item_progress.xml
Normal file
102
vector/src/main/res/layout/item_profile_matrix_item_progress.xml
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?riotx_background"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
android:minHeight="64dp"
|
||||
android:paddingLeft="@dimen/layout_horizontal_margin"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="@dimen/layout_horizontal_margin"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/matrixItemAvatar"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:scaleType="centerInside"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:src="@tools:sample/avatars" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/matrixItemAvatarDecoration"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
app:layout_constraintCircle="@+id/matrixItemAvatar"
|
||||
app:layout_constraintCircleAngle="135"
|
||||
app:layout_constraintCircleRadius="16dp"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:src="@drawable/ic_shield_trusted" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixItemTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawablePadding="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_primary"
|
||||
android:textSize="16sp"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/matrixItemSubtitle"
|
||||
app:layout_constraintEnd_toStartOf="@+id/matrixItemProgress"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@id/matrixItemAvatar"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_goneMarginStart="0dp"
|
||||
tools:text="@sample/matrix.json/data/displayName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/matrixItemSubtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawablePadding="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?riotx_text_secondary"
|
||||
android:textSize="12sp"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/matrixItemProgress"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@id/matrixItemAvatar"
|
||||
app:layout_constraintTop_toBottomOf="@id/matrixItemTitle"
|
||||
app:layout_goneMarginStart="0dp"
|
||||
tools:text="@sample/matrix.json/data/mxid" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/matrixItemProgress"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/matrixItemEditable"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/matrixItemEditable"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_arrow_right"
|
||||
android:tint="?riotx_text_secondary"
|
||||
android:visibility="visible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,19 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<!-- We will improve this later
|
||||
<style name="LoginLogo" parent="LoginLogoBase">
|
||||
<item name="layout_constraintEnd_toStartOf">@id/loginFormContainer</item>
|
||||
<item name="layout_constraintBottom_toBottomOf">parent</item>
|
||||
<item name="android:layout_height">0dp</item>
|
||||
<item name="layout_constraintHorizontal_chainStyle">packed</item>
|
||||
</style>
|
||||
|
||||
<style name="LoginFormContainer" parent="LoginFormContainerBase">
|
||||
<item name="layout_constraintWidth_percent">0.6</item>
|
||||
<item name="layout_constraintStart_toEndOf">@id/loginLogo</item>
|
||||
<item name="layout_constraintTop_toTopOf">parent</item>
|
||||
</style>
|
||||
-->
|
||||
|
||||
</resources>
|
||||
|
@ -1,8 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="LoginLogo.v21" parent="LoginLogoBase">
|
||||
<item name="android:transitionName">loginLogoTransition</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -992,6 +992,10 @@
|
||||
|
||||
<!-- Room settings: banned users -->
|
||||
<string name="room_settings_banned_users_title">Banned users</string>
|
||||
<plurals name="room_settings_banned_users_count">
|
||||
<item quantity="one">1 banned user</item>
|
||||
<item quantity="other">%d banned users</item>
|
||||
</plurals>
|
||||
|
||||
<!-- advanced -->
|
||||
<string name="room_settings_category_advanced_title">Advanced</string>
|
||||
@ -2499,6 +2503,7 @@ Not all features in Riot are implemented in Element yet. Main missing (and comin
|
||||
<string name="identity_server_set_alternative_notice_no_default">Enter the URL of an identity server</string>
|
||||
<string name="identity_server_set_alternative_submit">Submit</string>
|
||||
<string name="power_level_edit_title">Set role</string>
|
||||
<string name="power_level_title">Role</string>
|
||||
<string name="a11y_open_chat">Open chat</string>
|
||||
<string name="a11y_mute_microphone">Mute the microphone</string>
|
||||
<string name="a11y_unmute_microphone">Unmute the microphone</string>
|
||||
@ -2560,4 +2565,7 @@ Not all features in Riot are implemented in Element yet. Main missing (and comin
|
||||
|
||||
<string name="three_pid_revoke_invite_dialog_title">Revoke invite</string>
|
||||
<string name="three_pid_revoke_invite_dialog_content">Revoke invite to %1$s?</string>
|
||||
|
||||
<string name="member_banned_by">Banned by %1$s</string>
|
||||
<string name="failed_to_unban">Failed to UnBan user</string>
|
||||
</resources>
|
||||
|
@ -8,27 +8,9 @@
|
||||
<item name="android:paddingEnd">36dp</item>
|
||||
</style>
|
||||
|
||||
<item name="loginLogo" type="id" />
|
||||
<item name="loginFormScrollView" type="id" />
|
||||
<item name="loginFormContainer" type="id" />
|
||||
|
||||
<style name="LoginLogoBase">
|
||||
<item name="android:id">@id/loginLogo</item>
|
||||
<item name="android:layout_width">60dp</item>
|
||||
<item name="android:layout_height">60dp</item>
|
||||
<item name="android:src">@drawable/element_logo_green</item>
|
||||
<item name="android:importantForAccessibility">no</item>
|
||||
<item name="layout_constraintTop_toTopOf">parent</item>
|
||||
<item name="layout_constraintStart_toStartOf">parent</item>
|
||||
</style>
|
||||
|
||||
<style name="LoginLogo.v21" parent="LoginLogoBase" />
|
||||
|
||||
<style name="LoginLogo" parent="LoginLogo.v21">
|
||||
<item name="layout_constraintEnd_toEndOf">parent</item>
|
||||
<item name="android:layout_marginTop">48dp</item>
|
||||
</style>
|
||||
|
||||
<style name="LoginFormContainer">
|
||||
<item name="android:id">@id/loginFormContainer</item>
|
||||
<item name="android:paddingStart">36dp</item>
|
||||
@ -49,10 +31,10 @@
|
||||
</style>
|
||||
|
||||
<style name="LoginFormScrollView" parent="LoginFormScrollViewBase">
|
||||
<item name="layout_constraintTop_toBottomOf">@id/loginLogo</item>
|
||||
<item name="layout_constraintTop_toTopOf">parent</item>
|
||||
<item name="layout_constraintStart_toStartOf">parent</item>
|
||||
<item name="android:layout_height">0dp</item>
|
||||
<item name="android:layout_marginTop">24dp</item>
|
||||
<item name="android:layout_marginTop">72dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Style.Vector.Login.Button" parent="VectorButtonStyle">
|
||||
|
@ -24,6 +24,7 @@
|
||||
app:fragment="im.vector.riotx.features.settings.VectorSettingsPreferencesFragment" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
app:isPreferenceVisible="@bool/false_not_implemented"
|
||||
android:enabled="@bool/false_not_implemented"
|
||||
android:icon="@drawable/ic_settings_root_call"
|
||||
android:title="@string/preference_voice_and_video"
|
||||
|
Loading…
Reference in New Issue
Block a user