Skip to content
Snippets Groups Projects
Commit bd955eec authored by Taras's avatar Taras
Browse files

Add blur for circles

parent 4c465ce4
No related branches found
No related tags found
No related merge requests found
......@@ -2,9 +2,12 @@ package org.futo.circles.feature.circles
import androidx.lifecycle.asFlow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.withContext
import org.futo.circles.core.extensions.getKnownUsersFlow
import org.futo.circles.core.feature.workspace.SharedCircleDataSource
import org.futo.circles.core.feature.workspace.SpacesTreeAccountDataSource
import org.futo.circles.core.model.CIRCLES_SPACE_ACCOUNT_DATA_KEY
......@@ -25,18 +28,34 @@ class CirclesDataSource @Inject constructor(
private val sharedCircleDataSource: SharedCircleDataSource
) {
private val roomIdsToUnblurProfile = MutableStateFlow<Set<String>>(emptySet())
fun getCirclesFlow() = combine(
MatrixSessionProvider.getSessionOrThrow().roomService()
.getRoomSummariesLive(roomSummaryQueryParams { excludeType = null })
.asFlow(),
MatrixSessionProvider.getSessionOrThrow().getKnownUsersFlow(),
roomIdsToUnblurProfile,
MatrixSessionProvider.getSessionOrThrow().roomService().getChangeMembershipsLive().asFlow()
) { roomSummaries, _ ->
withContext(Dispatchers.IO) { buildCirclesList(roomSummaries) }
) { roomSummaries, knownUsers, roomIdsToUnblur, _ ->
withContext(Dispatchers.IO) {
buildCirclesList(
roomSummaries,
knownUsers.map { it.userId }.toSet(),
roomIdsToUnblur
)
}
}.distinctUntilChanged()
private fun buildCirclesList(list: List<RoomSummary>): List<CircleListItem> {
private fun buildCirclesList(
list: List<RoomSummary>,
knownUsersIds: Set<String>,
roomIdsToUnblur: Set<String>
): List<CircleListItem> {
val invites =
list.filter { isInviteToCircleTimeline(it) }.map { it.toInviteCircleListItem() }
list.filter { isInviteToCircleTimeline(it) }.map { it.toInviteCircleListItem(
shouldBlurIconFor(it, knownUsersIds, roomIdsToUnblur)
) }
val joinedCirclesSpaceIds = getJoinedCirclesIds()
val joinedCircles = list.filter { isJoinedCircle(it, joinedCirclesSpaceIds) }
......@@ -88,4 +107,19 @@ class CirclesDataSource @Inject constructor(
addAll(items)
}
}
private fun shouldBlurIconFor(
roomSummary: RoomSummary,
knownUserIds: Set<String>,
roomIdsToUnblur: Set<String>
): Boolean {
val isKnownUser = knownUserIds.contains(roomSummary.inviterId)
val isRoomUnbluredByUser = roomIdsToUnblur.contains(roomSummary.roomId)
val hasIcon = roomSummary.avatarUrl.isNotEmpty()
return !isKnownUser && !isRoomUnbluredByUser && hasIcon
}
fun unblurProfileImageFor(id: String) {
roomIdsToUnblurProfile.update { set -> set.toMutableSet().apply { add(id) } }
}
}
\ No newline at end of file
......@@ -81,6 +81,9 @@ class CirclesFragment : Fragment(org.futo.circles.core.R.layout.fragment_rooms),
onRoomClicked = { roomListItem -> onRoomListItemClicked(roomListItem) },
onInviteClicked = { roomListItem, isAccepted ->
onInviteClicked(roomListItem, isAccepted)
},
onUnblurProfileIconClicked = { roomListItem ->
viewModel.unblurProfileIcon(roomListItem)
}
).also { listAdapter = it }
bindToFab(binding.fbAddRoom)
......
......@@ -15,12 +15,14 @@ import org.futo.circles.core.feature.room.invite.InviteRequestsDataSource
import org.futo.circles.core.model.LoadingData
import org.futo.circles.core.provider.MatrixSessionProvider
import org.futo.circles.core.utils.getTimelineRoomFor
import org.futo.circles.model.CircleListItem
import org.futo.circles.model.GroupListItem
import org.matrix.android.sdk.api.session.getRoomSummary
import javax.inject.Inject
@HiltViewModel
class CirclesViewModel @Inject constructor(
dataSource: CirclesDataSource,
private val dataSource: CirclesDataSource,
private val inviteRequestsDataSource: InviteRequestsDataSource,
private val createRoomDataSource: CreateRoomDataSource
) : ViewModel() {
......@@ -55,4 +57,8 @@ class CirclesViewModel @Inject constructor(
}
}
fun unblurProfileIcon(roomListItem: CircleListItem) {
dataSource.unblurProfileImageFor(roomListItem.id)
}
}
\ No newline at end of file
......@@ -12,7 +12,8 @@ enum class CirclesListItemViewType { JoinedCircle, InvitedCircle, Header }
class CirclesListAdapter(
private val onRoomClicked: (CircleListItem) -> Unit,
private val onInviteClicked: (CircleListItem, Boolean) -> Unit
private val onInviteClicked: (CircleListItem, Boolean) -> Unit,
private val onUnblurProfileIconClicked: (CircleListItem) -> Unit
) : BaseRvAdapter<CircleListItem, CirclesViewHolder>(PayloadIdEntityCallback { old, new ->
if (new is JoinedCircleListItem && old is JoinedCircleListItem) {
CircleListItemPayload(
......@@ -44,6 +45,9 @@ class CirclesListAdapter(
parent = parent,
onInviteClicked = { position, isAccepted ->
onInviteClicked(getItem(position), isAccepted)
},
onShowProfileIconClicked = { position ->
onUnblurProfileIconClicked(getItem(position))
}
)
......
......@@ -2,7 +2,6 @@ package org.futo.circles.feature.circles.list
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import org.futo.circles.R
......@@ -23,10 +22,6 @@ import org.futo.circles.model.JoinedCircleListItem
abstract class CirclesViewHolder(view: View) : RecyclerView.ViewHolder(view) {
abstract fun bind(data: CircleListItem)
protected fun setIcon(groupIcon: ImageView, avatarUrl: String?, title: String) {
groupIcon.loadProfileIcon(avatarUrl, title)
}
protected fun setTitle(titleView: TextView, title: String) {
titleView.text = title
}
......@@ -50,7 +45,7 @@ class JoinedCircleViewHolder(
if (data !is JoinedCircleListItem) return
with(binding) {
setIcon(ivCircle, data.info.avatarUrl, data.info.title)
ivCircle.loadProfileIcon(data.info.avatarUrl, data.info.title)
setTitle(tvCircleTitle, data.info.title)
setFollowingCount(data.followingCount)
setFollowedByCount(data.followedByCount)
......@@ -89,7 +84,8 @@ class JoinedCircleViewHolder(
class InvitedCircleViewHolder(
parent: ViewGroup,
onInviteClicked: (Int, Boolean) -> Unit
onInviteClicked: (Int, Boolean) -> Unit,
onShowProfileIconClicked: (Int) -> Unit
) : CirclesViewHolder(inflate(parent, ListItemInvitedCircleBinding::inflate)) {
private companion object : ViewBindingHolder
......@@ -99,13 +95,19 @@ class InvitedCircleViewHolder(
init {
onClick(binding.btnAccept) { position -> onInviteClicked(position, true) }
onClick(binding.btnDecline) { position -> onInviteClicked(position, false) }
onClick(binding.ivCircle) { position -> onShowProfileIconClicked(position) }
}
override fun bind(data: CircleListItem) {
if (data !is InvitedCircleListItem) return
with(binding) {
setIcon(ivCircle, data.info.avatarUrl, data.info.title)
tvShowProfileImage.setIsVisible(data.shouldBlurIcon)
ivCircle.loadProfileIcon(
data.info.avatarUrl,
data.info.title,
applyBlur = data.shouldBlurIcon
)
setTitle(tvCircleTitle, data.info.title)
binding.tvInvitedBy.text =
context.getString(
......
......@@ -47,10 +47,11 @@ fun RoomSummary.toJoinedCircleListItem(isShared: Boolean = false) = JoinedCircle
knockRequestsCount = getKnocksCount(getTimelineRoomFor(roomId)?.roomId ?: "")
)
fun RoomSummary.toInviteCircleListItem() = InvitedCircleListItem(
fun RoomSummary.toInviteCircleListItem(shouldBlurIcon: Boolean) = InvitedCircleListItem(
id = roomId,
info = toRoomInfo(),
inviterName = getInviterName()
inviterName = getInviterName(),
shouldBlurIcon = shouldBlurIcon
)
private fun RoomSummary.getFollowersCount(): Int =
......
......@@ -38,5 +38,6 @@ data class InvitedCircleListItem(
override val id: String,
override val info: RoomInfo,
val inviterName: String,
val shouldBlurIcon: Boolean
) : CircleRoomListItem(id, info, Membership.INVITE)
......@@ -24,6 +24,23 @@
app:strokeWidth="1dp"
tools:src="@color/blue" />
<TextView
android:id="@+id/tvShowProfileImage"
style="@style/body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawablePadding="-4dp"
android:text="@string/show"
android:textColor="@color/white"
android:visibility="gone"
app:drawableTint="@color/white"
app:drawableTopCompat="@drawable/ic_seen"
app:layout_constraintBottom_toBottomOf="@id/ivCircle"
app:layout_constraintEnd_toEndOf="@id/ivCircle"
app:layout_constraintStart_toStartOf="@id/ivCircle"
app:layout_constraintTop_toTopOf="@id/ivCircle"
tools:visibility="visible" />
<TextView
android:id="@+id/tvCircleTitle"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment