mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-24 10:51:27 +01:00
Add avatar picker and defaults.
This commit is contained in:
committed by
Greyson Parrelli
parent
0093e1d3eb
commit
ed23c3fe7c
@@ -106,7 +106,7 @@ public final class AvatarImageView extends AppCompatImageView {
|
||||
|
||||
outlinePaint = ThemeUtil.isDarkTheme(context) ? DARK_THEME_OUTLINE_PAINT : LIGHT_THEME_OUTLINE_PAINT;
|
||||
|
||||
unknownRecipientDrawable = new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20).asDrawable(context, AvatarColor.UNKNOWN.colorInt(), inverted);
|
||||
unknownRecipientDrawable = new ResourceContactPhoto(R.drawable.ic_profile_outline_40, R.drawable.ic_profile_outline_20).asDrawable(context, AvatarColor.UNKNOWN, inverted);
|
||||
blurred = false;
|
||||
chatColors = null;
|
||||
}
|
||||
@@ -248,7 +248,7 @@ public final class AvatarImageView extends AppCompatImageView {
|
||||
requestManager.clear(this);
|
||||
if (fallbackPhotoProvider != null) {
|
||||
setImageDrawable(fallbackPhotoProvider.getPhotoForRecipientWithoutName()
|
||||
.asDrawable(getContext(), AvatarColor.UNKNOWN.colorInt(), inverted));
|
||||
.asDrawable(getContext(), AvatarColor.UNKNOWN, inverted));
|
||||
} else {
|
||||
setImageDrawable(unknownRecipientDrawable);
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public final class AvatarImageView extends AppCompatImageView {
|
||||
{
|
||||
Drawable fallback = Util.firstNonNull(fallbackPhotoProvider, Recipient.DEFAULT_FALLBACK_PHOTO_PROVIDER)
|
||||
.getPhotoForGroup()
|
||||
.asDrawable(getContext(), color.colorInt());
|
||||
.asDrawable(getContext(), color);
|
||||
|
||||
GlideApp.with(this)
|
||||
.load(avatarBytes)
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import org.thoughtcrime.securesms.R
|
||||
import java.util.Objects
|
||||
|
||||
/**
|
||||
* Custom View for Tabs which will render bold text when the view is selected
|
||||
*/
|
||||
class BoldSelectionTabItem @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private lateinit var unselectedTextView: TextView
|
||||
private lateinit var selectedTextView: TextView
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
|
||||
unselectedTextView = findViewById(android.R.id.text1)
|
||||
selectedTextView = findViewById(R.id.text1_bold)
|
||||
|
||||
unselectedTextView.doAfterTextChanged {
|
||||
selectedTextView.text = it
|
||||
}
|
||||
}
|
||||
|
||||
fun select() {
|
||||
unselectedTextView.alpha = 0f
|
||||
selectedTextView.alpha = 1f
|
||||
}
|
||||
|
||||
fun unselect() {
|
||||
unselectedTextView.alpha = 1f
|
||||
selectedTextView.alpha = 0f
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun registerListeners(tabLayout: ControllableTabLayout) {
|
||||
val newTabListener = NewTabListener()
|
||||
val onTabSelectedListener = OnTabSelectedListener()
|
||||
|
||||
(0 until tabLayout.tabCount).mapNotNull { tabLayout.getTabAt(it) }.forEach {
|
||||
newTabListener.onNewTab(it)
|
||||
|
||||
if (it.isSelected) {
|
||||
onTabSelectedListener.onTabSelected(it)
|
||||
} else {
|
||||
onTabSelectedListener.onTabUnselected(it)
|
||||
}
|
||||
}
|
||||
|
||||
tabLayout.setNewTabListener(newTabListener)
|
||||
tabLayout.addOnTabSelectedListener(onTabSelectedListener)
|
||||
}
|
||||
}
|
||||
|
||||
private class NewTabListener : ControllableTabLayout.NewTabListener {
|
||||
override fun onNewTab(tab: TabLayout.Tab) {
|
||||
val customView = tab.customView
|
||||
if (customView == null) {
|
||||
tab.setCustomView(R.layout.bold_selection_tab_item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class OnTabSelectedListener : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab) {
|
||||
val view = Objects.requireNonNull(tab.customView) as BoldSelectionTabItem
|
||||
view.select()
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab) {
|
||||
val view = Objects.requireNonNull(tab.customView) as BoldSelectionTabItem
|
||||
view.unselect()
|
||||
}
|
||||
|
||||
override fun onTabReselected(tab: TabLayout.Tab) = Unit
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import org.thoughtcrime.securesms.R
|
||||
|
||||
class ButtonStripItemView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private val iconView: ImageView
|
||||
private val labelView: TextView
|
||||
|
||||
init {
|
||||
inflate(context, R.layout.button_strip_item_view, this)
|
||||
|
||||
iconView = findViewById(R.id.icon)
|
||||
labelView = findViewById(R.id.label)
|
||||
|
||||
val array = context.obtainStyledAttributes(attrs, R.styleable.ButtonStripItemView)
|
||||
|
||||
val icon = array.getDrawable(R.styleable.ButtonStripItemView_bsiv_icon)
|
||||
val contentDescription = array.getString(R.styleable.ButtonStripItemView_bsiv_icon_contentDescription)
|
||||
val label = array.getString(R.styleable.ButtonStripItemView_bsiv_label)
|
||||
|
||||
iconView.setImageDrawable(icon)
|
||||
iconView.contentDescription = contentDescription
|
||||
labelView.text = label
|
||||
|
||||
array.recycle()
|
||||
}
|
||||
|
||||
fun setOnIconClickedListener(onIconClickedListener: (() -> Unit)?) {
|
||||
iconView.setOnClickListener { onIconClickedListener?.invoke() }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.components.recyclerview
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.annotation.Px
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
|
||||
/**
|
||||
* Decoration which will add an equal amount of space between each item in a grid.
|
||||
*/
|
||||
open class GridDividerDecoration(
|
||||
private val spanCount: Int,
|
||||
@Px private val space: Int
|
||||
) : RecyclerView.ItemDecoration() {
|
||||
|
||||
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||
return setItemOffsets(parent.getChildAdapterPosition(view), view, outRect)
|
||||
}
|
||||
|
||||
protected fun setItemOffsets(position: Int, view: View, outRect: Rect) {
|
||||
val column = position % spanCount
|
||||
val isRtl = ViewUtil.isRtl(view)
|
||||
|
||||
val distanceFromEnd = spanCount - 1 - column
|
||||
|
||||
val spaceStart = (column / spanCount.toFloat()) * space
|
||||
val spaceEnd = (distanceFromEnd / spanCount.toFloat()) * space
|
||||
|
||||
outRect.setStart(spaceStart.toInt(), isRtl)
|
||||
outRect.setEnd(spaceEnd.toInt(), isRtl)
|
||||
outRect.bottom = space
|
||||
}
|
||||
|
||||
private fun Rect.setEnd(end: Int, isRtl: Boolean) {
|
||||
if (isRtl) {
|
||||
left = end
|
||||
} else {
|
||||
right = end
|
||||
}
|
||||
}
|
||||
|
||||
private fun Rect.setStart(start: Int, isRtl: Boolean) {
|
||||
if (isRtl) {
|
||||
right = start
|
||||
} else {
|
||||
left = start
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user