Adding user avatar and color for current location option

This commit is contained in:
Maxime Naturel 2022-03-02 17:23:26 +01:00
parent 42fca9bd6f
commit b11f7f20e1
6 changed files with 45 additions and 15 deletions

View file

@ -30,6 +30,9 @@ import im.vector.app.R
import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.platform.VectorBaseFragment
import im.vector.app.databinding.FragmentLocationSharingBinding import im.vector.app.databinding.FragmentLocationSharingBinding
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider
import org.matrix.android.sdk.api.util.MatrixItem
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import javax.inject.Inject import javax.inject.Inject
@ -37,7 +40,9 @@ import javax.inject.Inject
* We should consider using SupportMapFragment for a out of the box lifecycle handling * We should consider using SupportMapFragment for a out of the box lifecycle handling
*/ */
class LocationSharingFragment @Inject constructor( class LocationSharingFragment @Inject constructor(
private val urlMapProvider: UrlMapProvider private val urlMapProvider: UrlMapProvider,
private val avatarRenderer: AvatarRenderer,
private val matrixItemColorProvider: MatrixItemColorProvider
) : VectorBaseFragment<FragmentLocationSharingBinding>() { ) : VectorBaseFragment<FragmentLocationSharingBinding>() {
private val viewModel: LocationSharingViewModel by fragmentViewModel() private val viewModel: LocationSharingViewModel by fragmentViewModel()
@ -45,6 +50,8 @@ class LocationSharingFragment @Inject constructor(
// Keep a ref to handle properly the onDestroy callback // Keep a ref to handle properly the onDestroy callback
private var mapView: WeakReference<MapView>? = null private var mapView: WeakReference<MapView>? = null
private var hasRenderedUserAvatar = false
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationSharingBinding { override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLocationSharingBinding {
return FragmentLocationSharingBinding.inflate(inflater, container, false) return FragmentLocationSharingBinding.inflate(inflater, container, false)
} }
@ -108,6 +115,7 @@ class LocationSharingFragment @Inject constructor(
override fun invalidate() = withState(viewModel) { state -> override fun invalidate() = withState(viewModel) { state ->
views.mapView.render(state.toMapState()) views.mapView.render(state.toMapState())
views.shareLocationGpsLoading.isGone = state.lastKnownLocation != null views.shareLocationGpsLoading.isGone = state.lastKnownLocation != null
updateUserAvatar(state.userItem)
} }
private fun handleLocationNotAvailableError() { private fun handleLocationNotAvailableError() {
@ -123,7 +131,6 @@ class LocationSharingFragment @Inject constructor(
private fun initOptionsPicker() { private fun initOptionsPicker() {
// TODO // TODO
// set avatar and user color for the current user location option
// change the options dynamically depending on the current chosen location // change the options dynamically depending on the current chosen location
views.shareLocationOptionsPicker.setOptions(LocationSharingOption.PINNED) views.shareLocationOptionsPicker.setOptions(LocationSharingOption.PINNED)
views.shareLocationOptionsPicker.optionPinned.debouncedClicks { views.shareLocationOptionsPicker.optionPinned.debouncedClicks {
@ -136,4 +143,14 @@ class LocationSharingFragment @Inject constructor(
// TODO // TODO
} }
} }
private fun updateUserAvatar(userItem: MatrixItem.UserItem?) {
userItem?.takeUnless { hasRenderedUserAvatar }
?.let {
hasRenderedUserAvatar = true
avatarRenderer.render(it, views.shareLocationOptionsPicker.optionUserCurrent.iconView)
val tintColor = matrixItemColorProvider.getColor(it)
views.shareLocationOptionsPicker.optionUserCurrent.setIconBackgroundTint(tintColor)
}
}
} }

View file

@ -26,6 +26,7 @@ import im.vector.app.core.extensions.exhaustive
import im.vector.app.core.platform.VectorViewModel import im.vector.app.core.platform.VectorViewModel
import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider
import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.util.toMatrixItem
class LocationSharingViewModel @AssistedInject constructor( class LocationSharingViewModel @AssistedInject constructor(
@Assisted private val initialState: LocationSharingViewState, @Assisted private val initialState: LocationSharingViewState,
@ -45,9 +46,14 @@ class LocationSharingViewModel @AssistedInject constructor(
init { init {
locationTracker.start(this) locationTracker.start(this)
setUserItem()
createPin() createPin()
} }
private fun setUserItem() {
setState { copy(userItem = session.getUser(session.myUserId)?.toMatrixItem()) }
}
private fun createPin() { private fun createPin() {
locationPinProvider.create(session.myUserId) { locationPinProvider.create(session.myUserId) {
setState { setState {

View file

@ -20,6 +20,7 @@ import android.graphics.drawable.Drawable
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksState
import im.vector.app.R import im.vector.app.R
import org.matrix.android.sdk.api.util.MatrixItem
enum class LocationSharingMode(@StringRes val titleRes: Int) { enum class LocationSharingMode(@StringRes val titleRes: Int) {
STATIC_SHARING(R.string.location_activity_title_static_sharing), STATIC_SHARING(R.string.location_activity_title_static_sharing),
@ -29,6 +30,7 @@ enum class LocationSharingMode(@StringRes val titleRes: Int) {
data class LocationSharingViewState( data class LocationSharingViewState(
val roomId: String, val roomId: String,
val mode: LocationSharingMode, val mode: LocationSharingMode,
val userItem: MatrixItem.UserItem? = null,
val lastKnownLocation: LocationData? = null, val lastKnownLocation: LocationData? = null,
val pinDrawable: Drawable? = null val pinDrawable: Drawable? = null
) : MavericksState { ) : MavericksState {

View file

@ -18,10 +18,10 @@ package im.vector.app.features.location.view
import android.content.Context import android.content.Context
import android.content.res.TypedArray import android.content.res.TypedArray
import android.graphics.drawable.Drawable
import android.util.AttributeSet import android.util.AttributeSet
import android.util.TypedValue
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
@ -36,6 +36,9 @@ class LocationSharingOptionView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) { ) : ConstraintLayout(context, attrs, defStyleAttr) {
val iconView: ImageView
get() = binding.shareLocationOptionIcon
private val binding = ViewLocationSharingOptionBinding.inflate( private val binding = ViewLocationSharingOptionBinding.inflate(
LayoutInflater.from(context), LayoutInflater.from(context),
this this
@ -57,11 +60,12 @@ class LocationSharingOptionView @JvmOverloads constructor(
} }
} }
fun setIcon(icon: Drawable) { fun setIconBackgroundTint(@ColorInt color: Int) {
binding.shareLocationOptionIcon.setImageDrawable(icon) val bkg = binding.shareLocationOptionIcon.background?.let {
} val backgroundDrawable = DrawableCompat.wrap(binding.shareLocationOptionIcon.background)
DrawableCompat.setTint(backgroundDrawable, color)
fun setIconBackground(bkg: Drawable) { backgroundDrawable
}
binding.shareLocationOptionIcon.background = bkg binding.shareLocationOptionIcon.background = bkg
} }
@ -78,15 +82,15 @@ class LocationSharingOptionView @JvmOverloads constructor(
) )
val description = typedArray.getString(R.styleable.LocationSharingOptionView_iconDescription) val description = typedArray.getString(R.styleable.LocationSharingOptionView_iconDescription)
binding.shareLocationOptionIcon.setImageDrawable(icon) iconView.setImageDrawable(icon)
val bkg = background?.let { val bkg = background?.let {
val backgroundDrawable = DrawableCompat.wrap(it) val backgroundDrawable = DrawableCompat.wrap(it)
DrawableCompat.setTint(backgroundDrawable, backgroundTint) DrawableCompat.setTint(backgroundDrawable, backgroundTint)
backgroundDrawable backgroundDrawable
} ?: background }
binding.shareLocationOptionIcon.background = bkg iconView.background = bkg
binding.shareLocationOptionIcon.setPadding(padding) iconView.setPadding(padding)
binding.shareLocationOptionIcon.contentDescription = description iconView.contentDescription = description
} }
private fun setTitle(typedArray: TypedArray) { private fun setTitle(typedArray: TypedArray) {

View file

@ -29,7 +29,7 @@
android:contentDescription="@string/a11y_location_share_icon" android:contentDescription="@string/a11y_location_share_icon"
tools:background="@drawable/circle" tools:background="@drawable/circle"
tools:backgroundTint="?colorPrimary" tools:backgroundTint="?colorPrimary"
tools:padding="10dp" tools:padding="11dp"
tools:src="@drawable/ic_attachment_location_white" /> tools:src="@drawable/ic_attachment_location_white" />
<TextView <TextView

View file

@ -11,6 +11,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:icon="@drawable/ic_attachment_location_white" app:icon="@drawable/ic_attachment_location_white"
app:iconPadding="11dp"
app:iconBackground="@drawable/circle" app:iconBackground="@drawable/circle"
app:iconBackgroundTint="?colorPrimary" app:iconBackgroundTint="?colorPrimary"
app:iconDescription="@string/a11y_location_share_option_pinned_icon" app:iconDescription="@string/a11y_location_share_option_pinned_icon"