mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 22:42:45 +01:00
Fix missing avatars in widgets (#1238)
This commit is contained in:
parent
efafd2094a
commit
e03b0dfa01
@ -1,18 +1,20 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.graphics.PorterDuff
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.databinding.ItemAccountBinding
|
import io.github.wulkanowy.databinding.ItemAccountBinding
|
||||||
|
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
import io.github.wulkanowy.utils.nickOrName
|
import io.github.wulkanowy.utils.nickOrName
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter<WidgetConfigureAdapter.ItemViewHolder>() {
|
class WidgetConfigureAdapter @Inject constructor() :
|
||||||
|
RecyclerView.Adapter<WidgetConfigureAdapter.ItemViewHolder>() {
|
||||||
|
|
||||||
var items = emptyList<Pair<Student, Boolean>>()
|
var items = emptyList<Pair<Student, Boolean>>()
|
||||||
|
|
||||||
@ -27,16 +29,31 @@ class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter<Widget
|
|||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||||
val (student, isCurrent) = items[position]
|
val (student, isCurrent) = items[position]
|
||||||
|
val context = holder.binding.root.context
|
||||||
|
val checkBackgroundColor = context.getThemeAttrColor(R.attr.colorSurface)
|
||||||
|
val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor)
|
||||||
|
val isDuplicatedStudent = items.filter {
|
||||||
|
val studentToCompare = it.first
|
||||||
|
|
||||||
|
studentToCompare.studentId == student.studentId
|
||||||
|
&& studentToCompare.schoolSymbol == student.schoolSymbol
|
||||||
|
&& studentToCompare.symbol == student.symbol
|
||||||
|
}.size > 1
|
||||||
|
|
||||||
with(holder.binding) {
|
with(holder.binding) {
|
||||||
accountItemName.text = "${student.nickOrName} ${student.className}"
|
accountItemName.text = "${student.nickOrName} ${student.className}"
|
||||||
accountItemSchool.text = student.schoolName
|
accountItemSchool.text = student.schoolName
|
||||||
|
accountItemImage.setImageDrawable(avatar)
|
||||||
|
|
||||||
with(accountItemImage) {
|
with(accountItemAccountType) {
|
||||||
val colorImage = if (isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student)
|
||||||
else context.getThemeAttrColor(R.attr.colorOnSurface, 153)
|
isVisible = isDuplicatedStudent
|
||||||
|
}
|
||||||
|
|
||||||
setColorFilter(colorImage, PorterDuff.Mode.SRC_IN)
|
with(accountItemCheck) {
|
||||||
|
isVisible = isCurrent
|
||||||
|
borderColor = checkBackgroundColor
|
||||||
|
circleColor = checkBackgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
root.setOnClickListener { onClickListener(student) }
|
root.setOnClickListener { onClickListener(student) }
|
||||||
|
@ -13,6 +13,8 @@ import android.content.Intent
|
|||||||
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
@ -25,6 +27,8 @@ import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
|||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
import io.github.wulkanowy.utils.nickOrName
|
import io.github.wulkanowy.utils.nickOrName
|
||||||
@ -72,7 +76,8 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
|
|
||||||
fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId"
|
fun getThemeWidgetKey(appWidgetId: Int) = "timetable_widget_theme_$appWidgetId"
|
||||||
|
|
||||||
fun getCurrentThemeWidgetKey(appWidgetId: Int) = "timetable_widget_current_theme_$appWidgetId"
|
fun getCurrentThemeWidgetKey(appWidgetId: Int) =
|
||||||
|
"timetable_widget_current_theme_$appWidgetId"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
@ -88,21 +93,29 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
private suspend fun onUpdate(context: Context, intent: Intent) {
|
private suspend fun onUpdate(context: Context, intent: Intent) {
|
||||||
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
||||||
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
|
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
|
||||||
val student = getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
|
val student =
|
||||||
|
getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId)
|
||||||
updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student)
|
updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
||||||
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
|
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
|
||||||
val student = getStudent(sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0), toggledWidgetId)
|
val student = getStudent(
|
||||||
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0))
|
sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0),
|
||||||
|
toggledWidgetId
|
||||||
|
)
|
||||||
|
val savedDate =
|
||||||
|
LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0))
|
||||||
val date = when (buttonType) {
|
val date = when (buttonType) {
|
||||||
BUTTON_RESET -> now().nextOrSameSchoolDay
|
BUTTON_RESET -> now().nextOrSameSchoolDay
|
||||||
BUTTON_NEXT -> savedDate.nextSchoolDay
|
BUTTON_NEXT -> savedDate.nextSchoolDay
|
||||||
BUTTON_PREV -> savedDate.previousSchoolDay
|
BUTTON_PREV -> savedDate.previousSchoolDay
|
||||||
else -> now().nextOrSameSchoolDay
|
else -> now().nextOrSameSchoolDay
|
||||||
}
|
}
|
||||||
if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType)
|
if (!buttonType.isNullOrBlank()) analytics.logEvent(
|
||||||
|
"changed_timetable_widget_day",
|
||||||
|
"button" to buttonType
|
||||||
|
)
|
||||||
updateWidget(context, toggledWidgetId, date, student)
|
updateWidget(context, toggledWidgetId, date, student)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,9 +134,15 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) {
|
private fun updateWidget(
|
||||||
|
context: Context,
|
||||||
|
appWidgetId: Int,
|
||||||
|
date: LocalDate,
|
||||||
|
student: Student?
|
||||||
|
) {
|
||||||
val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
|
val savedConfigureTheme = sharedPref.getLong(getThemeWidgetKey(appWidgetId), 0)
|
||||||
val isSystemDarkMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
val isSystemDarkMode =
|
||||||
|
context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||||
var currentTheme = 0L
|
var currentTheme = 0L
|
||||||
var layoutId = R.layout.widget_timetable
|
var layoutId = R.layout.widget_timetable
|
||||||
|
|
||||||
@ -134,21 +153,28 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
|
|
||||||
val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)
|
val nextNavIntent = createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)
|
||||||
val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)
|
val prevNavIntent = createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)
|
||||||
val resetNavIntent = createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET)
|
val resetNavIntent =
|
||||||
|
createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET)
|
||||||
val adapterIntent = Intent(context, TimetableWidgetService::class.java)
|
val adapterIntent = Intent(context, TimetableWidgetService::class.java)
|
||||||
.apply {
|
.apply {
|
||||||
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
//make Intent unique
|
//make Intent unique
|
||||||
action = appWidgetId.toString()
|
action = appWidgetId.toString()
|
||||||
}
|
}
|
||||||
val accountIntent = PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId,
|
val accountIntent = PendingIntent.getActivity(
|
||||||
|
context, -Int.MAX_VALUE + appWidgetId,
|
||||||
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
|
Intent(context, TimetableWidgetConfigureActivity::class.java).apply {
|
||||||
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
|
addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK)
|
||||||
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
putExtra(EXTRA_APPWIDGET_ID, appWidgetId)
|
||||||
putExtra(EXTRA_FROM_PROVIDER, true)
|
putExtra(EXTRA_FROM_PROVIDER, true)
|
||||||
}, FLAG_UPDATE_CURRENT)
|
}, FLAG_UPDATE_CURRENT
|
||||||
val appIntent = PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id,
|
)
|
||||||
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT)
|
val appIntent = PendingIntent.getActivity(
|
||||||
|
context,
|
||||||
|
MainView.Section.TIMETABLE.id,
|
||||||
|
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true),
|
||||||
|
FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
|
||||||
val remoteView = RemoteViews(context.packageName, layoutId).apply {
|
val remoteView = RemoteViews(context.packageName, layoutId).apply {
|
||||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||||
@ -160,6 +186,11 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
R.id.timetableWidgetName,
|
R.id.timetableWidgetName,
|
||||||
student?.nickOrName ?: context.getString(R.string.all_no_data)
|
student?.nickOrName ?: context.getString(R.string.all_no_data)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
student?.let {
|
||||||
|
setImageViewBitmap(R.id.timetableWidgetAccount, context.createAvatarBitmap(it))
|
||||||
|
}
|
||||||
|
|
||||||
setRemoteAdapter(R.id.timetableWidgetList, adapterIntent)
|
setRemoteAdapter(R.id.timetableWidgetList, adapterIntent)
|
||||||
setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent)
|
setOnClickPendingIntent(R.id.timetableWidgetNext, nextNavIntent)
|
||||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent)
|
setOnClickPendingIntent(R.id.timetableWidgetPrev, prevNavIntent)
|
||||||
@ -181,13 +212,20 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNavIntent(context: Context, code: Int, appWidgetId: Int, buttonType: String): PendingIntent {
|
private fun createNavIntent(
|
||||||
return PendingIntent.getBroadcast(context, code,
|
context: Context,
|
||||||
|
code: Int,
|
||||||
|
appWidgetId: Int,
|
||||||
|
buttonType: String
|
||||||
|
): PendingIntent {
|
||||||
|
return PendingIntent.getBroadcast(
|
||||||
|
context, code,
|
||||||
Intent(context, TimetableWidgetProvider::class.java).apply {
|
Intent(context, TimetableWidgetProvider::class.java).apply {
|
||||||
action = ACTION_APPWIDGET_UPDATE
|
action = ACTION_APPWIDGET_UPDATE
|
||||||
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
||||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
||||||
}, FLAG_UPDATE_CURRENT)
|
}, FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
private suspend fun getStudent(studentId: Long, appWidgetId: Int) = try {
|
||||||
@ -208,4 +246,29 @@ class TimetableWidgetProvider : HiltBroadcastReceiver() {
|
|||||||
}
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Context.createAvatarBitmap(student: Student): Bitmap {
|
||||||
|
val avatarColor = if (student.avatarColor == -2937041L) {
|
||||||
|
getCompatColor(R.color.colorPrimaryLight).toLong()
|
||||||
|
} else {
|
||||||
|
student.avatarColor
|
||||||
|
}
|
||||||
|
val avatarDrawable = createNameInitialsDrawable(student.nickOrName, avatarColor, 0.5f)
|
||||||
|
|
||||||
|
val avatarBitmap =
|
||||||
|
if (avatarDrawable.intrinsicWidth <= 0 || avatarDrawable.intrinsicHeight <= 0) {
|
||||||
|
Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)
|
||||||
|
} else {
|
||||||
|
Bitmap.createBitmap(
|
||||||
|
avatarDrawable.intrinsicWidth,
|
||||||
|
avatarDrawable.intrinsicHeight,
|
||||||
|
Bitmap.Config.ARGB_8888
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val canvas = Canvas(avatarBitmap)
|
||||||
|
avatarDrawable.setBounds(0, 0, canvas.width, canvas.height)
|
||||||
|
avatarDrawable.draw(canvas)
|
||||||
|
return avatarBitmap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user