Room profile: continue working on UI

This commit is contained in:
ganfra 2019-11-26 13:22:07 +01:00
parent 8aab46804b
commit ab4cab05cf
12 changed files with 276 additions and 63 deletions

View file

@ -30,6 +30,8 @@ data class RoomSummary(
val topic: String = "",
val avatarUrl: String = "",
val isDirect: Boolean = false,
val joinedMembersCount: Int? = 0,
val invitedMembersCount: Int? = 0,
val latestPreviewableEvent: TimelineEvent? = null,
val otherMemberIds: List<String> = emptyList(),
val notificationCount: Int = 0,

View file

@ -60,6 +60,8 @@ internal class RoomSummaryMapper @Inject constructor(
avatarUrl = roomSummaryEntity.avatarUrl ?: "",
isDirect = roomSummaryEntity.isDirect,
latestPreviewableEvent = latestEvent,
joinedMembersCount = roomSummaryEntity.joinedMembersCount,
invitedMembersCount = roomSummaryEntity.invitedMembersCount,
otherMemberIds = roomSummaryEntity.otherMemberIds.toList(),
highlightCount = roomSummaryEntity.highlightCount,
notificationCount = roomSummaryEntity.notificationCount,

View file

@ -16,16 +16,20 @@
package im.vector.riotx.core.epoxy.profiles
import android.content.res.ColorStateList
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.core.widget.ImageViewCompat
import com.airbnb.epoxy.EpoxyAttribute
import com.airbnb.epoxy.EpoxyModelClass
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.themes.ThemeUtils
@EpoxyModelClass(layout = R.layout.item_profile_action)
abstract class ProfileItemAction : VectorEpoxyModel<ProfileItemAction.Holder>() {
@ -39,6 +43,8 @@ abstract class ProfileItemAction : VectorEpoxyModel<ProfileItemAction.Holder>()
@EpoxyAttribute
var editable: Boolean = true
@EpoxyAttribute
var destructive: Boolean = false
@EpoxyAttribute
lateinit var listener: View.OnClickListener
override fun bind(holder: Holder) {
@ -46,6 +52,12 @@ abstract class ProfileItemAction : VectorEpoxyModel<ProfileItemAction.Holder>()
holder.view.setOnClickListener(listener)
holder.editable.isVisible = editable
holder.title.text = title
val tintColor = if (destructive) {
ContextCompat.getColor(holder.view.context, R.color.riotx_notice)
} else {
ThemeUtils.getColor(holder.view.context, R.attr.riotx_text_primary)
}
holder.title.setTextColor(tintColor)
holder.subtitle.setTextOrHide(subtitle)
if (iconRes != 0) {
holder.icon.setImageResource(iconRes)

View file

@ -17,8 +17,11 @@
package im.vector.riotx.features.roomprofile
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import com.airbnb.epoxy.TypedEpoxyController
import im.vector.riotx.R
import im.vector.riotx.core.epoxy.DividerItem_
import im.vector.riotx.core.epoxy.dividerItem
import im.vector.riotx.core.epoxy.profiles.profileItemAction
import im.vector.riotx.core.epoxy.profiles.profileItemSection
@ -33,7 +36,10 @@ class RoomProfileController @Inject constructor(private val stringProvider: Stri
interface Callback {
fun onLearnMoreClicked()
fun onMemberListClicked()
fun onNotificationsClicked()
fun onUploadsClicked()
fun onSettingsClicked()
fun onLeaveRoomClicked()
}
override fun buildModels(data: RoomProfileViewState?) {
@ -43,60 +49,88 @@ class RoomProfileController @Inject constructor(private val stringProvider: Stri
val roomSummary = data.roomSummary()
profileItemSection {
id("section_security")
title("Security")
}
// Security
buildSection(stringProvider.getString(R.string.room_profile_section_security))
val learnMoreSubtitle = if (data.isEncrypted) {
R.string.room_profile_encrypted_subtitle
} else {
R.string.room_profile_not_encrypted_subtitle
}
profileItemAction {
id("action_learn_more")
title("Learn more")
editable(true)
subtitle(stringProvider.getString(learnMoreSubtitle))
listener { _ ->
callback?.onLearnMoreClicked()
}
}
dividerItem {
id("action_learn_more_divider")
}
profileItemSection {
id("section_options")
title("Options")
}
val numberOfMembers = (roomSummary?.otherMemberIds?.size ?: 0) + 1
profileItemAction {
iconRes(R.drawable.ic_person_outline_black)
id("action_member_list")
title(stringProvider.getString(R.string.room_profile_member_list_title, numberOfMembers))
editable(true)
listener { _ ->
callback?.onMemberListClicked()
}
}
dividerItem {
id("action_member_list_divider")
}
profileItemAction {
iconRes(R.drawable.ic_room_actions_settings)
id("action_settings")
title("Room settings")
editable(true)
listener { _ ->
callback?.onSettingsClicked()
}
}
buildAction(
id = "learn_more",
title = stringProvider.getString(R.string.room_profile_section_security_learn_more),
subtitle = stringProvider.getString(learnMoreSubtitle),
action = { callback?.onLearnMoreClicked() }
)
// More
buildSection(stringProvider.getString(R.string.room_profile_section_more))
buildAction(
id = "settings",
title = stringProvider.getString(R.string.room_profile_section_more_settings),
icon = R.drawable.ic_room_profile_settings,
action = { callback?.onSettingsClicked() }
)
buildAction(
id = "notifications",
title = stringProvider.getString(R.string.room_profile_section_more_notifications),
icon = R.drawable.ic_room_profile_notification,
action = { callback?.onNotificationsClicked() }
)
val numberOfMembers = roomSummary?.joinedMembersCount?.toString() ?: "-"
buildAction(
id = "member_list",
title = stringProvider.getString(R.string.room_profile_section_more_member_list, numberOfMembers),
icon = R.drawable.ic_room_profile_member_list,
action = { callback?.onMemberListClicked() }
)
buildAction(
id = "uploads",
title = stringProvider.getString(R.string.room_profile_section_more_uploads),
icon = R.drawable.ic_room_profile_uploads,
action = { callback?.onUploadsClicked() }
)
buildAction(
id = "leave",
title = stringProvider.getString(R.string.room_profile_section_more_leave),
divider = false,
destructive = true,
action = { callback?.onLeaveRoomClicked() }
)
}
private fun buildSection(title: String) {
profileItemSection {
id("section_$title")
title(title)
}
}
private fun buildAction(
id: String,
title: String,
subtitle: String? = null,
@DrawableRes icon: Int = 0,
destructive: Boolean = false,
divider: Boolean = true,
action: () -> Unit
) {
profileItemAction {
iconRes(icon)
id("action_$id")
subtitle(subtitle)
destructive(destructive)
title(title)
listener { _ ->
action()
}
}
DividerItem_()
.id("divider_$title")
.addIf(divider, this)
}
}

View file

@ -61,7 +61,6 @@ class RoomProfileFragment @Inject constructor(
roomProfileRecyclerView.setHasFixedSize(true)
roomProfileRecyclerView.layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
roomProfileRecyclerView.adapter = roomProfileController.adapter
}
override fun onDestroyView() {
@ -77,7 +76,8 @@ class RoomProfileFragment @Inject constructor(
} else {
roomProfileNameView.text = it.displayName
roomProfileNameView2.text = it.displayName
roomProfileIdView.text = it.roomId
// Use canonical alias when PR with alias management will be merged
roomProfileAliasView.text = it.roomId
roomProfileTopicView.setTextOrHide(it.topic)
avatarRenderer.render(it, roomProfileAvatarView)
}
@ -92,12 +92,23 @@ class RoomProfileFragment @Inject constructor(
}
override fun onMemberListClicked() {
vectorBaseActivity.notImplemented("Room member list")
vectorBaseActivity.notImplemented("See room member list")
}
override fun onSettingsClicked() {
vectorBaseActivity.notImplemented("Room settings")
vectorBaseActivity.notImplemented("See Room settings")
}
override fun onNotificationsClicked() {
vectorBaseActivity.notImplemented("See notifications")
}
override fun onUploadsClicked() {
vectorBaseActivity.notImplemented("See uploads")
}
override fun onLeaveRoomClicked() {
vectorBaseActivity.notImplemented("Leave room")
}
}

View file

@ -0,0 +1,51 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M17,21V19C17,16.7909 15.2091,15 13,15H5C2.7909,15 1,16.7909 1,19V21"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M9,11C11.2091,11 13,9.2091 13,7C13,4.7909 11.2091,3 9,3C6.7909,3 5,4.7909 5,7C5,9.2091 6.7909,11 9,11Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M23,21V19C22.9986,17.1771 21.765,15.5857 20,15.13"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M16,3.13C17.7699,3.5832 19.0078,5.178 19.0078,7.005C19.0078,8.832 17.7699,10.4268 16,10.88"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
</vector>

View file

@ -0,0 +1,25 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M2,16C1.4477,16 1,16.4477 1,17C1,17.5523 1.4477,18 2,18V16ZM5,9H4H5ZM19,9H20H19ZM13.73,21L14.595,21.5018C14.7744,21.1924 14.775,20.8108 14.5965,20.5009C14.418,20.191 14.0876,20 13.73,20V21ZM10.27,21V20C9.9124,20 9.582,20.191 9.4035,20.5009C9.225,20.8108 9.2255,21.1924 9.405,21.5018L10.27,21ZM22,16H2V18H22V16ZM2,18C4.2091,18 6,16.2091 6,14H4C4,15.1046 3.1046,16 2,16V18ZM6,14V9H4V14H6ZM6,9C6,5.6863 8.6863,3 12,3V1C7.5817,1 4,4.5817 4,9H6ZM12,3C15.3137,3 18,5.6863 18,9H20C20,4.5817 16.4183,1 12,1V3ZM18,9V14H20V9H18ZM18,14C18,16.2091 19.7909,18 22,18V16C20.8954,16 20,15.1046 20,14H18ZM12.865,20.4982C12.6861,20.8066 12.3565,20.9965 12,20.9965V22.9965C13.0696,22.9965 14.0583,22.427 14.595,21.5018L12.865,20.4982ZM12,20.9965C11.6435,20.9965 11.3139,20.8066 11.135,20.4982L9.405,21.5018C9.9417,22.427 10.9304,22.9965 12,22.9965V20.9965ZM10.27,22H13.73V20H10.27V22Z"
android:fillColor="#61708B"/>
</vector>

View file

@ -0,0 +1,30 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M19.4,15C19.1277,15.6171 19.2583,16.3378 19.73,16.82L19.79,16.88C20.1656,17.2551 20.3766,17.7642 20.3766,18.295C20.3766,18.8258 20.1656,19.3349 19.79,19.71C19.4149,20.0856 18.9058,20.2966 18.375,20.2966C17.8442,20.2966 17.3351,20.0856 16.96,19.71L16.9,19.65C16.4178,19.1783 15.6971,19.0477 15.08,19.32C14.4755,19.5791 14.0826,20.1724 14.08,20.83V21C14.08,22.1046 13.1846,23 12.08,23C10.9754,23 10.08,22.1046 10.08,21V20.91C10.0642,20.2327 9.6359,19.6339 9,19.4C8.3829,19.1277 7.6622,19.2583 7.18,19.73L7.12,19.79C6.7449,20.1656 6.2358,20.3766 5.705,20.3766C5.1742,20.3766 4.6651,20.1656 4.29,19.79C3.9144,19.4149 3.7034,18.9058 3.7034,18.375C3.7034,17.8442 3.9144,17.3351 4.29,16.96L4.35,16.9C4.8217,16.4178 4.9524,15.6971 4.68,15.08C4.4209,14.4755 3.8276,14.0826 3.17,14.08H3C1.8954,14.08 1,13.1846 1,12.08C1,10.9754 1.8954,10.08 3,10.08H3.09C3.7673,10.0642 4.3661,9.6359 4.6,9C4.8724,8.3829 4.7417,7.6622 4.27,7.18L4.21,7.12C3.8345,6.7449 3.6234,6.2358 3.6234,5.705C3.6234,5.1742 3.8345,4.6651 4.21,4.29C4.5851,3.9144 5.0942,3.7034 5.625,3.7034C6.1558,3.7034 6.6649,3.9144 7.04,4.29L7.1,4.35C7.5822,4.8217 8.3029,4.9524 8.92,4.68H9C9.6045,4.4209 9.9974,3.8276 10,3.17V3C10,1.8954 10.8954,1 12,1C13.1046,1 14,1.8954 14,3V3.09C14.0026,3.7476 14.3955,4.3409 15,4.6C15.6171,4.8724 16.3378,4.7417 16.82,4.27L16.88,4.21C17.2551,3.8345 17.7642,3.6234 18.295,3.6234C18.8258,3.6234 19.3349,3.8345 19.71,4.21C20.0856,4.5851 20.2966,5.0942 20.2966,5.625C20.2966,6.1558 20.0856,6.6649 19.71,7.04L19.65,7.1C19.1783,7.5822 19.0477,8.3029 19.32,8.92V9C19.5791,9.6045 20.1724,9.9974 20.83,10H21C22.1046,10 23,10.8954 23,12C23,13.1046 22.1046,14 21,14H20.91C20.2524,14.0026 19.6591,14.3955 19.4,15Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
</vector>

View file

@ -0,0 +1,37 @@
<!--
~ 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M13,2H6C4.8954,2 4,2.8954 4,4V20C4,21.1046 4.8954,22 6,22H18C19.1046,22 20,21.1046 20,20V9L13,2Z"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:fillType="evenOdd"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
<path
android:pathData="M13,2V9H20"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="#00000000"
android:strokeColor="#61708B"
android:strokeLineCap="round"/>
</vector>

View file

@ -44,7 +44,7 @@
tools:text="Random" />
<TextView
android:id="@+id/roomProfileIdView"
android:id="@+id/roomProfileAliasView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"

View file

@ -5,10 +5,10 @@
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:background="?riotx_background"
android:minHeight="64dp"
android:paddingLeft="@dimen/layout_horizontal_margin"
android:paddingTop="8dp"
@ -22,11 +22,11 @@
android:layout_centerVertical="true"
android:scaleType="center"
android:tint="?riotx_text_secondary"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginStart="16dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/ic_room_profile_notification" />
<TextView
android:id="@+id/actionTitle"
@ -39,12 +39,13 @@
android:maxLines="2"
android:textColor="?riotx_text_primary"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@id/actionIcon"
app:layout_constraintBottom_toTopOf="@+id/actionSubtitle"
app:layout_constraintEnd_toStartOf="@+id/actionEditable"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintBottom_toTopOf="@+id/actionSubtitle"
app:layout_constraintStart_toEndOf="@id/actionIcon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="wrap"
app:layout_goneMarginStart="0dp"
tools:text="Learn more" />
<TextView
@ -58,12 +59,13 @@
android:maxLines="2"
android:textColor="?riotx_text_secondary"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@id/actionIcon"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/actionEditable"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/actionIcon"
app:layout_constraintTop_toBottomOf="@id/actionTitle"
app:layout_constraintWidth_default="wrap"
app:layout_goneMarginStart="0dp"
tools:text="Messages in this room are not end-to-end encrypted" />
@ -72,8 +74,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_right"
android:visibility="gone"
android:tint="?riotx_text_secondary"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"

View file

@ -21,6 +21,13 @@
<string name="room_profile_not_encrypted_subtitle">Messages in this room are not end-to-end encrypted.</string>
<string name="room_profile_encrypted_subtitle">Messages in this room are end-to-end encrypted.</string>
<string name="room_profile_member_list_title">"%1$d people"</string>
<string name="room_profile_section_security">Security</string>
<string name="room_profile_section_security_learn_more">Learn more</string>
<string name="room_profile_section_more">More</string>
<string name="room_profile_section_more_settings">Room settings</string>
<string name="room_profile_section_more_notifications">Notifications</string>
<string name="room_profile_section_more_member_list">"%1$s people"</string>
<string name="room_profile_section_more_uploads">Uploads</string>
<string name="room_profile_section_more_leave">Leave Room</string>
</resources>