diff --git a/jami-android/app/src/main/java/cx/ring/utils/DeviceUtils.kt b/jami-android/app/src/main/java/cx/ring/utils/DeviceUtils.kt index bd083dbc4ddb36479f324768dd820173201b420c..293fdab2c6bb67b3e01b9323e24de64fb871ad40 100644 --- a/jami-android/app/src/main/java/cx/ring/utils/DeviceUtils.kt +++ b/jami-android/app/src/main/java/cx/ring/utils/DeviceUtils.kt @@ -27,8 +27,12 @@ import io.reactivex.rxjava3.schedulers.Schedulers object DeviceUtils { fun isTv(context: Context): Boolean = - context.getSystemService(UiModeManager::class.java) - .currentModeType == Configuration.UI_MODE_TYPE_TELEVISION + try { + context.getSystemService(UiModeManager::class.java) + .currentModeType == Configuration.UI_MODE_TYPE_TELEVISION + } catch (e: Throwable) { + false + } fun getStatusBarHeight(context: Context): Int { val resourceId = context.resources diff --git a/jami-android/app/src/main/java/cx/ring/views/AvatarView.kt b/jami-android/app/src/main/java/cx/ring/views/AvatarView.kt new file mode 100644 index 0000000000000000000000000000000000000000..42c5487002c4e4ed3fdeb70198794f2558b0fba3 --- /dev/null +++ b/jami-android/app/src/main/java/cx/ring/views/AvatarView.kt @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2004-2024 Savoir-faire Linux Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +package cx.ring.views + +import android.content.Context +import android.graphics.Canvas +import android.util.AttributeSet +import android.view.View +import androidx.core.content.res.use +import cx.ring.R +import cx.ring.utils.BitmapUtils +import kotlin.math.min + +class AvatarView @JvmOverloads constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int = 0, defStyleRes: Int = 0) : + View(context, attrs, defStyleAttr, defStyleRes) { + + private var avatarDrawable: AvatarDrawable? = null + + init { + context.obtainStyledAttributes(attrs, R.styleable.AvatarView).use { typedArray -> + val uri = typedArray.getString(R.styleable.AvatarView_uri) + if (uri != null || isInEditMode) { + val username = typedArray.getString(R.styleable.AvatarView_username) + val displayName = typedArray.getString(R.styleable.AvatarView_displayName) + val avatar = typedArray.getDrawable(R.styleable.AvatarView_avatar) + val cropCircle = typedArray.getBoolean(R.styleable.AvatarView_cropCircle, true) + setAvatar(AvatarDrawable.Builder() + .withId(uri) + .withNameData(displayName, username) + .withPhoto(avatar?.let { BitmapUtils.drawableToBitmap(it) }) + .withCircleCrop(cropCircle) + .build(context)) + } + } + } + + /** Returns true if the avatar was set if it was previously empty. */ + fun setAvatar(avatar: AvatarDrawable?): Boolean { + val noPrevious = avatarDrawable == null + avatarDrawable = avatar + avatar?.setBounds(paddingLeft, paddingTop, width - paddingRight, height - paddingBottom) + invalidate() + return noPrevious + } + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + val measuredWidth = MeasureSpec.getSize(widthMeasureSpec) + val measuredHeight = MeasureSpec.getSize(heightMeasureSpec) + val paddingW = paddingLeft + paddingRight + val paddingH = paddingTop + paddingBottom + val size = min(measuredWidth - paddingW, measuredHeight - paddingH) + setMeasuredDimension(size + paddingW, size + paddingH) + } + + override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + avatarDrawable?.setBounds( + paddingLeft, + paddingTop, + w - paddingRight, + h - paddingBottom + ) + } + + override fun onDraw(canvas: Canvas) { + avatarDrawable?.draw(canvas) + } +} \ No newline at end of file diff --git a/jami-android/app/src/main/res/values/attrs.xml b/jami-android/app/src/main/res/values/attrs.xml index 8e026b93603e7f2433a631ae021e6a8d397a7463..9851c8dc995c39548bda6d21f0e9ab6da0577566 100644 --- a/jami-android/app/src/main/res/values/attrs.xml +++ b/jami-android/app/src/main/res/values/attrs.xml @@ -11,6 +11,14 @@ <attr name="text" format="string" /> </declare-styleable> + <declare-styleable name="AvatarView"> + <attr name="uri" format="string" /> + <attr name="username" format="string" /> + <attr name="displayName" format="string" /> + <attr name="avatar" format="reference" /> + <attr name="cropCircle" format="boolean" /> + </declare-styleable> + <declare-styleable name="SwitchButton"> <attr name="backColor" format="color|reference"/> <attr name="status" format="string"/>