8000 Fix null image generation for conversation icons by Choucroute-melba · Pull Request #445 · octoshrimpy/quik · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix null image generation for conversation icons #445

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,65 @@ package dev.octoshrimpy.quik.common.util.extensions

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Path
import android.util.TypedValue
import android.view.Gravity
import android.graphics.Canvas
import android.view.LayoutInflater
import android.view.View.GONE
import android.view.View.MeasureSpec
import android.view.View.VISIBLE
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout.LayoutParams
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.graphics.createBitmap
import androidx.core.graphics.drawable.IconCompat
import androidx.core.view.drawToBitmap
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.widget.TextViewCompat
import dev.octoshrimpy.quik.R
import dev.octoshrimpy.quik.common.util.Colors
import dev.octoshrimpy.quik.common.widget.AvatarView
import dev.octoshrimpy.quik.common.widget.QkTextView
import dev.octoshrimpy.quik.model.Conversation
import dev.octoshrimpy.quik.model.Recipient
import dev.octoshrimpy.quik.util.GlideApp
import dev.octoshrimpy.quik.util.tryOrNull
import timber.log.Timber

fun Conversation.getThemedIcon(context: Context, width: Int, height: Int): IconCompat {
return try {
val inflater = LayoutInflater.from(context)
val parent = ConstraintLayout(context).apply {
layoutParams = ConstraintLayout.LayoutParams(width, height)
}
val view = inflater.inflate(R.layout.group_avatar_view, parent, true).apply {
layoutParams = ConstraintLayout.LayoutParams(width, height)
}

var icon : IconCompat? = null
Timber.v("Photo not found, creating default icon")
val inflater = LayoutInflater.from(context)
val layout = FrameLayout(context)
layout.layout(0, 0, width, height)
layout.layoutParams = FrameLayout.LayoutParams(width, height)
val view = inflater.inflate(R.layout.group_avatar_view, layout)
view.layoutParams = FrameLayout.LayoutParams(width, height)
val avatar1 = view.findViewById<AvatarView>(R.id.avatar1)
val avatar2 = view.findViewById<AvatarView>(R.id.avatar2)
val avatar1Frame = view.findViewById<FrameLayout>(R.id.avatar1Frame)
val avatar1 = view.findViewById<AvatarView>(R.id.avatar1)
val avatar2 = view.findViewById<AvatarView>(R.id.avatar2)
val avatar1Frame = view.findViewById<FrameLayout>(R.id.avatar1Frame)

avatar1Frame.setBackgroundTint(when (recipients.size > 1) {
true -> context.resolveThemeColor(android.R.attr.windowBackground)
false -> context.getColorCompat(android.R.color.transparent)
})
avatar1Frame.updateLayoutParams<LayoutParams> {
matchConstraintPercentWidth = if (recipients.size > 1) 0.75f else 1.0f
}
avatar2.isVisible = recipients.size > 1
val multipleRecipients = recipients.size > 1

avatar1Frame.setBackgroundTint(
if (multipleRecipients)
context.resolveThemeColor(android.R.attr.windowBackground)
else
context.getColorCompat(android.R.color.transparent)
)
avatar1Frame.updateLayoutParams<ConstraintLayout.LayoutParams> {
matchConstraintPercentWidth = if (multipleRecipients) 0.75f else 1.0f
}
avatar2.isVisible = multipleRecipients

recipients.getOrNull(0).run(avatar1::setRecipient)
recipients.getOrNull(1).run(avatar2::setRecipient)
recipients.getOrNull(0)?.let(avatar1::setRecipient)
recipients.getOrNull(1)?.let(avatar2::setRecipient)

view.apply {
measure(
view.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
layout(0, 0, measuredWidth, measuredHeight)
}
view.layout(0, 0, view.measuredWidth, view.measuredHeight)

Timber.v("w: ${view.measuredWidth}; h: ${view.measuredHeight}")
val bitmap = createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
val canvas = android.graphics.Canvas(bitmap)
view.draw(canvas)
Timber.v("w: ${view.measuredWidth}; h: ${view.measuredHeight}")

icon = IconCompat.createWithBitmap(bitmap)
return icon
val bitmap = createBitmap(view.measuredWidth, view.measuredHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
view.draw(canvas)

IconCompat.createWithBitmap(bitmap)
} catch (e: Exception) {
Timber.e(e, "Error creating default icon")
IconCompat.createWithResource(context, R.mipmap.ic_shortcut_people)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,68 +41,73 @@ fun Recipient.getThemedIcon(context: Context, theme: Colors.Theme, width: Int, h
}
if(icon == null) {
// If there is no contact or no photo, create the default icon using the avatar_view layout
val inflater = LayoutInflater.from(context)
< 8000 span class='blob-code-inner blob-code-marker js-skip-tagsearch' data-code-marker="-"> val container = FrameLayout(context)
container.layoutParams = FrameLayout.LayoutParams(width, height)
val view = inflater.inflate(R.layout.avatar_view, container)
val textView = view.findViewById<QkTextView>(R.id.initial)
val iconView = view.findViewById<ImageView>(R.id.icon)
val photoView = view.findViewById<ImageView>(R.id.photo)
try {
val inflater = LayoutInflater.from(context)
val container = FrameLayout(context)
container.layoutParams = FrameLayout.LayoutParams(width, height)
val view = inflater.inflate(R.layout.avatar_view, container)
val textView = view.findViewById<QkTextView>(R.id.initial)
val iconView = view.findViewById<ImageView>(R.id.icon)
val photoView = view.findViewById<ImageView>(R.id.photo)

photoView.visibility = GONE
view.setBackgroundColor(theme.theme)
view.setBackgroundTint(theme.theme)
textView.setTextColor(theme.textPrimary)
TextViewCompat.setAutoSizeTextTypeWithDefaults(textView, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, height * 0.5f)
iconView.layoutParams = FrameLayout.LayoutParams((width * 0.5).toInt(), (height * 0.5).toInt(),
Gravity.CENTER)
photoView.visibility = GONE
view.setBackgroundColor(theme.theme)
view.setBackgroundTint(theme.theme)
textView.setTextColor(theme.textPrimary)
TextViewCompat.setAutoSizeTextTypeWithDefaults(textView, TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, height * 0.5f)
iconView.layoutParams = FrameLayout.LayoutParams((width * 0.5).toInt(), (height * 0.5).toInt(),
Gravity.CENTER)

if(contact != null) {
val initials = contact!!.name
.substringBefore(',')
.split(" ")
.filter { name -> name.isNotEmpty() }
.map { name -> name[0] }
.filter { initial -> initial.isLetterOrDigit() }
.map { initial -> initial.toString() }
if (initials.isNotEmpty()) {
textView.text =
if (initials.size > 1) initials.first() + initials.last() else initials.first()
iconView.visibility = GONE
} else {
textView.text = null
if(contact != null) {
val initials = contact!!.name
.substringBefore(',')
.split(" ")
.filter { name -> name.isNotEmpty() }
.map { name -> name[0] }
.filter { initial -> initial.isLetterOrDigit() }
.map { initial -> initial.toString() }
if (initials.isNotEmpty()) {
textView.text =
if (initials.size > 1) initials.first() + initials.last() else initials.first()
iconView.visibility = GONE
} else {
textView.text = null
iconView.visibility = VISIBLE
}
}
else {
textView.visibility = GONE
iconView.visibility = VISIBLE
iconView.setTint(theme.textPrimary)
}
}
else {
textView.visibility = GONE
iconView.visibility = VISIBLE
iconView.setTint(theme.textPrimary)
}

container.apply {
measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
layout(0, 0, measuredWidth, measuredHeight)
}
container.apply {
measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
)
layout(0, 0, measuredWidth, measuredHeight)
}

Timber.v("w: ${container.measuredWidth}; h: ${container.measuredHeight}")
val bitmap = createBitmap(container.measuredWidth, container.measuredHeight, Bitmap.Config.ARGB_8888)
val canvas = android.graphics.Canvas(bitmap)
canvas.clipPath(Path().apply {
addCircle(
(width / 2).toFloat(),
(height / 2).toFloat(),
(width / 2).toFloat(),
Path.Direction.CW
)
})
container.draw(canvas)
val bitmap = createBitmap(container.measuredWidth, container.measuredHeight, Bitmap.Config.ARGB_8888)
val canvas = android.graphics.Canvas(bitmap)
canvas.clipPath(Path().apply {
addCircle(
(width / 2).toFloat(),
(height / 2).toFloat(),
(width / 2).toFloat(),
Path.Direction.CW
)
})
container.draw(canvas)

icon = IconCompat.createWithBitmap(bitmap)
icon = IconCompat.createWithBitmap(bitmap)
}
catch (e: Exception) {
Timber.e(e)
return IconCompat.createWithResource(context, R.mipmap.ic_shortcut_person)
}
}
return icon
}
Expand Down
0