Apply shapeable avatars

This commit is contained in:
Arne 2024-09-01 18:48:29 +02:00
parent 0ecebdf2f0
commit 54a4b6758b
18 changed files with 122 additions and 31 deletions

View file

@ -7,6 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21"
}
}
@ -16,6 +17,7 @@ plugins {
}
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
repositories {
google()

View file

@ -43,12 +43,11 @@
android:layout_height="wrap_content"
android:padding="@dimen/card_padding_regular">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/details_contact_badge"
android:layout_width="@dimen/avatar_on_details_screen_size"
android:layout_height="@dimen/avatar_on_details_screen_size"
android:layout_alignParentTop="true"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo"
android:scaleType="centerCrop" />
<LinearLayout

View file

@ -47,14 +47,13 @@
android:layout_height="wrap_content"
android:padding="@dimen/card_padding_regular">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/avater"
android:layout_width="@dimen/avatar_on_details_screen_size"
android:layout_height="@dimen/avatar_on_details_screen_size"
android:layout_alignParentTop="true"
android:layout_marginEnd="@dimen/avatar_item_distance"
android:contentDescription="@string/account_image_description"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:contentDescription="@string/account_image_description" />
<LinearLayout
android:layout_width="fill_parent"

View file

@ -50,12 +50,11 @@
android:layout_marginBottom="32dp"
android:paddingHorizontal="@dimen/card_padding_regular">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/your_photo"
android:layout_width="@dimen/avatar_on_details_screen_size"
android:layout_height="@dimen/avatar_on_details_screen_size"
android:layout_alignParentStart="true"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo"
android:layout_marginEnd="@dimen/avatar_item_distance" />
<LinearLayout

View file

@ -17,13 +17,12 @@
android:paddingBottom="8dp"
android:paddingTop="8dp">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/account_image"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:contentDescription="@string/account_image_description"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:contentDescription="@string/account_image_description" />
<LinearLayout
android:layout_width="fill_parent"

View file

@ -9,13 +9,12 @@
android:background="?selectableItemBackground"
android:padding="@dimen/list_padding">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/avatar"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
<RelativeLayout
android:layout_width="wrap_content"

View file

@ -13,13 +13,12 @@
android:layout_height="wrap_content"
android:padding="@dimen/list_padding">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/contact_photo"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
<LinearLayout
android:layout_width="wrap_content"

View file

@ -19,13 +19,12 @@
android:orientation="horizontal"
android:padding="8dp">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/conversation_image"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_alignParentStart="true"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
<RelativeLayout
android:layout_width="fill_parent"

View file

@ -27,15 +27,14 @@
android:paddingHorizontal="8dp"
android:paddingVertical="4dp">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/message_photo"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginEnd="0dp"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
<LinearLayout
android:id="@+id/message_box"

View file

@ -37,12 +37,11 @@
android:layout_marginStart="0dp"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/message_photo"
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
</LinearLayout>

View file

@ -20,7 +20,7 @@
android:layout_centerVertical="true"
android:text="@string/load_more_messages" />
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/message_photo"
android:layout_width="32dp"
android:layout_height="32dp"
@ -28,8 +28,7 @@
android:layout_alignParentTop="true"
android:layout_marginEnd="-1.5dp"
android:padding="0dp"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
<TextView
android:id="@+id/status_message"

View file

@ -7,11 +7,10 @@
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:padding="2dp">
<com.google.android.material.imageview.ShapeableImageView
<eu.siacs.conversations.ui.widget.AvatarView
android:id="@+id/avatar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:shapeAppearance="@style/ShapeAppearanceOverlay.Photo" />
android:scaleType="centerCrop" />
</eu.siacs.conversations.ui.widget.SquareFrameLayout>
</layout>

View file

@ -48,6 +48,18 @@
<item>SEND_LOCATION</item>
</string-array>
<string-array name="avatars_shape">
<item>@string/avater_shape_rounded_square</item>
<item>@string/avater_shape_oval</item>
<item>@string/avater_shape_square</item>
</string-array>
<string-array name="avatars_shape_values">
<item>rounded_square</item>
<item>oval</item>
<item>square</item>
</string-array>
<string-array name="picture_compression_values">
<item>never</item>
<item>auto</item>

View file

@ -54,4 +54,5 @@
<bool name="send_link_previews">true</bool>
<bool name="compose_rich_text">true</bool>
<bool name="auto_accept_unmetered">true</bool>
<string name="avatar_shape">rounded_square</string>
</resources>

View file

@ -55,4 +55,7 @@
<dimen name="small_margin">4dp</dimen>
<dimen name="actionbar_text_size">20sp</dimen>
<dimen name="material_input_text_to_prefix_suffix_padding">0dp</dimen>
<dimen name="avatar_corners_radius">8dp</dimen>
</resources>

View file

@ -1076,4 +1076,10 @@
<string name="welcome_to_monocles_chat">Welcome to monocles chat</string>
<string name="monocles_chat_intro_description">monocles chat is an app that connects you to a global network called Jabber. This network includes services, called gateways, for chatting with other networks such as SMS, IRC, Matrix, and more.</string>
<string name="how_the_xmpp_network_works">How the XMPP network works</string>
<string name="avater_shape_oval">Oval</string>
<string name="avater_shape_rounded_square">Rounded Square</string>
<string name="avater_shape_square">Square</string>
<string name="pref_avatars_shape">Avatars shape</string>
<string name="pref_avatar_shape_summary">Allows you to select avatars shape globally</string>
</resources>

View file

@ -81,6 +81,13 @@
app:colorpicker_showAlpha="false" />
</PreferenceCategory>>
<PreferenceCategory android:title="@string/appearance">
<ListPreference
android:defaultValue="@string/avatar_shape"
android:key="avatar_shape"
android:entries="@array/avatars_shape"
android:entryValues="@array/avatars_shape_values"
android:summary="@string/pref_avatar_shape_summary"
android:title="@string/pref_avatars_shape" />
<SwitchPreferenceCompat
android:defaultValue="@bool/use_green_background"
android:icon="@drawable/ic_forum_24dp"

View file

@ -0,0 +1,71 @@
package eu.siacs.conversations.ui.widget
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Outline
import androidx.preference.PreferenceManager
import android.util.AttributeSet
import android.view.View
import android.view.ViewOutlineProvider
import androidx.appcompat.widget.AppCompatImageView
import eu.siacs.conversations.R
class AvatarView : AppCompatImageView {
private var currentShape: String = ""
private val preferencesListener = SharedPreferences.OnSharedPreferenceChangeListener { _, _ -> invalidateShape() }
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun onAttachedToWindow() {
super.onAttachedToWindow()
invalidateShape()
PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(preferencesListener)
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
PreferenceManager.getDefaultSharedPreferences(context).unregisterOnSharedPreferenceChangeListener(preferencesListener)
}
private fun invalidateShape() {
val shape = PreferenceManager.getDefaultSharedPreferences(context).getString("avatar_shape", context.getString(R.string.avatar_shape))
if (shape == currentShape) {
return
}
when {
shape == "oval" -> {
clipToOutline = true
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
outline.setOval(0, 0, view.width, view.height)
}
}
}
shape == "rounded_square" -> {
clipToOutline = true
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: Outline) {
val maxRadius = minOf(view.width, view.height) / 2f
val radius = minOf(context.resources.getDimension(R.dimen.avatar_corners_radius), maxRadius)
outline.setRoundRect(0, 0, view.width, view.height, radius)
}
}
}
shape == "square" -> {
clipToOutline = false
outlineProvider = ViewOutlineProvider.BACKGROUND
}
}
currentShape = shape!!
}
}