mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2024-11-27 04:23:33 -06:00
Improve error handling in horizontal tile on dashboard (#2053)
This commit is contained in:
parent
650cbd5a10
commit
fdce2cf477
@ -6,12 +6,18 @@ import io.github.wulkanowy.sdk.pojo.Message as SdkMessage
|
|||||||
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
|
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
|
||||||
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
||||||
|
|
||||||
fun List<SdkMessage>.mapToEntities(student: Student, mailbox: Mailbox?, allMailboxes: List<Mailbox>): List<Message> = map {
|
fun List<SdkMessage>.mapToEntities(
|
||||||
|
student: Student,
|
||||||
|
mailbox: Mailbox?,
|
||||||
|
allMailboxes: List<Mailbox>
|
||||||
|
): List<Message> = map {
|
||||||
Message(
|
Message(
|
||||||
messageGlobalKey = it.globalKey,
|
messageGlobalKey = it.globalKey,
|
||||||
mailboxKey = mailbox?.globalKey ?: allMailboxes.find { box ->
|
mailboxKey = mailbox?.globalKey ?: allMailboxes.find { box ->
|
||||||
box.fullName == it.mailbox
|
box.fullName == it.mailbox
|
||||||
}?.globalKey!!,
|
}?.globalKey.let { mailboxKey ->
|
||||||
|
requireNotNull(mailboxKey) { "Can't find ${it.mailbox} in $allMailboxes" }
|
||||||
|
},
|
||||||
email = student.email,
|
email = student.email,
|
||||||
messageId = it.id,
|
messageId = it.id,
|
||||||
correspondents = it.correspondents,
|
correspondents = it.correspondents,
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.data.repositories
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.Resource
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.dao.MailboxDao
|
import io.github.wulkanowy.data.db.dao.MailboxDao
|
||||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||||
@ -14,9 +14,7 @@ import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
|||||||
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
|
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
|
||||||
import io.github.wulkanowy.data.mappers.mapFromEntities
|
import io.github.wulkanowy.data.mappers.mapFromEntities
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.data.networkBoundResource
|
|
||||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||||
import io.github.wulkanowy.data.toFirstResult
|
|
||||||
import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
|
import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.sdk.pojo.Folder
|
import io.github.wulkanowy.sdk.pojo.Folder
|
||||||
@ -194,7 +192,9 @@ class MessageRepository @Inject constructor(
|
|||||||
it.isEmpty() || isExpired || forceRefresh
|
it.isEmpty() || isExpired || forceRefresh
|
||||||
},
|
},
|
||||||
query = { mailboxDao.loadAll(student.email, student.symbol, student.schoolSymbol) },
|
query = { mailboxDao.loadAll(student.email, student.symbol, student.schoolSymbol) },
|
||||||
fetch = { sdk.init(student).getMailboxes().mapToEntities(student) },
|
fetch = {
|
||||||
|
sdk.init(student).getMailboxes().mapToEntities(student)
|
||||||
|
},
|
||||||
saveFetchResult = { old, new ->
|
saveFetchResult = { old, new ->
|
||||||
mailboxDao.deleteAll(old uniqueSubtract new)
|
mailboxDao.deleteAll(old uniqueSubtract new)
|
||||||
mailboxDao.insertAll(new uniqueSubtract old)
|
mailboxDao.insertAll(new uniqueSubtract old)
|
||||||
@ -207,7 +207,11 @@ class MessageRepository @Inject constructor(
|
|||||||
val mailbox = getMailboxByStudentUseCase(student)
|
val mailbox = getMailboxByStudentUseCase(student)
|
||||||
|
|
||||||
return if (mailbox == null) {
|
return if (mailbox == null) {
|
||||||
getMailboxes(student, forceRefresh = true).toFirstResult()
|
getMailboxes(student, forceRefresh = true)
|
||||||
|
.onResourceError { throw it }
|
||||||
|
.onResourceSuccess { Timber.i("Found ${it.size} new mailboxes") }
|
||||||
|
.waitForResult()
|
||||||
|
|
||||||
getMailboxByStudentUseCase(student)
|
getMailboxByStudentUseCase(student)
|
||||||
} else mailbox
|
} else mailbox
|
||||||
}
|
}
|
||||||
|
@ -33,18 +33,27 @@ sealed class DashboardItem(val type: Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class HorizontalGroup(
|
data class HorizontalGroup(
|
||||||
val unreadMessagesCount: Int? = null,
|
val unreadMessagesCount: Cell<Int?>? = null,
|
||||||
val attendancePercentage: Double? = null,
|
val attendancePercentage: Cell<Double>? = null,
|
||||||
val luckyNumber: Int? = null,
|
val luckyNumber: Cell<Int>? = null,
|
||||||
override val error: Throwable? = null,
|
override val error: Throwable? = null,
|
||||||
override val isLoading: Boolean = false
|
override val isLoading: Boolean = false
|
||||||
) : DashboardItem(Type.HORIZONTAL_GROUP) {
|
) : DashboardItem(Type.HORIZONTAL_GROUP) {
|
||||||
|
|
||||||
|
data class Cell<T>(
|
||||||
|
val data: T?,
|
||||||
|
val error: Boolean,
|
||||||
|
val isLoading: Boolean,
|
||||||
|
) {
|
||||||
|
val isHidden: Boolean
|
||||||
|
get() = data == null && !error && !isLoading
|
||||||
|
}
|
||||||
|
|
||||||
override val isDataLoaded
|
override val isDataLoaded
|
||||||
get() = unreadMessagesCount != null || attendancePercentage != null || luckyNumber != null
|
get() = unreadMessagesCount?.isLoading == false || attendancePercentage?.isLoading == false || luckyNumber?.isLoading == false
|
||||||
|
|
||||||
val isFullDataLoaded
|
val isFullDataLoaded
|
||||||
get() = luckyNumber != -1 && attendancePercentage != -1.0 && unreadMessagesCount != -1
|
get() = luckyNumber?.isLoading != true && attendancePercentage?.isLoading != true && unreadMessagesCount?.isLoading != true
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Grades(
|
data class Grades(
|
||||||
|
@ -226,50 +226,71 @@ class DashboardPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
|
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
|
||||||
flow {
|
flow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
|
||||||
val mailbox = messageRepository.getMailboxByStudent(student)
|
|
||||||
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
||||||
|
|
||||||
val flowSuccess = flowOf(Resource.Success(null))
|
val flowSuccess = flowOf(Resource.Success(null))
|
||||||
|
|
||||||
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
||||||
.mapResourceData {
|
.mapResourceData {
|
||||||
it ?: LuckyNumber(0, LocalDate.now(), 0)
|
it ?: LuckyNumber(0, LocalDate.now(), 0)
|
||||||
}
|
}
|
||||||
|
.onResourceError { errorHandler.dispatch(it) }
|
||||||
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess
|
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
val messageFLow = messageRepository.getMessages(
|
val messageFLow = flatResourceFlow {
|
||||||
student = student,
|
val mailbox = messageRepository.getMailboxByStudent(student)
|
||||||
mailbox = mailbox,
|
|
||||||
folder = MessageFolder.RECEIVED,
|
|
||||||
forceRefresh = forceRefresh
|
|
||||||
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
|
|
||||||
|
|
||||||
val attendanceFlow = attendanceSummaryRepository.getAttendanceSummary(
|
messageRepository.getMessages(
|
||||||
student = student,
|
student = student,
|
||||||
semester = semester,
|
mailbox = mailbox,
|
||||||
subjectId = -1,
|
folder = MessageFolder.RECEIVED,
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
|
)
|
||||||
|
}
|
||||||
|
.onResourceError { errorHandler.dispatch(it) }
|
||||||
|
.takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
|
val attendanceFlow = flatResourceFlow {
|
||||||
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
|
attendanceSummaryRepository.getAttendanceSummary(
|
||||||
|
student = student,
|
||||||
|
semester = semester,
|
||||||
|
subjectId = -1,
|
||||||
|
forceRefresh = forceRefresh
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.onResourceError { errorHandler.dispatch(it) }
|
||||||
|
.takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
emitAll(
|
emitAll(
|
||||||
combine(
|
combine(
|
||||||
luckyNumberFlow,
|
flow = luckyNumberFlow,
|
||||||
messageFLow,
|
flow2 = messageFLow,
|
||||||
attendanceFlow
|
flow3 = attendanceFlow,
|
||||||
) { luckyNumberResource, messageResource, attendanceResource ->
|
) { luckyNumberResource, messageResource, attendanceResource ->
|
||||||
val resList = listOf(luckyNumberResource, messageResource, attendanceResource)
|
val resList = listOf(luckyNumberResource, messageResource, attendanceResource)
|
||||||
resList.firstNotNullOfOrNull { it.errorOrNull }?.let { throw it }
|
|
||||||
val isLoading = resList.any { it is Resource.Loading }
|
|
||||||
|
|
||||||
val luckyNumber = luckyNumberResource.dataOrNull?.luckyNumber
|
|
||||||
val messageCount = messageResource.dataOrNull?.count { it.unread }
|
|
||||||
val attendancePercentage = attendanceResource.dataOrNull?.calculatePercentage()
|
|
||||||
|
|
||||||
DashboardItem.HorizontalGroup(
|
DashboardItem.HorizontalGroup(
|
||||||
isLoading = isLoading,
|
isLoading = resList.any { it is Resource.Loading },
|
||||||
attendancePercentage = if (attendancePercentage == 0.0 && isLoading) -1.0 else attendancePercentage,
|
error = resList.map { it.errorOrNull }.let { errors ->
|
||||||
unreadMessagesCount = if (messageCount == 0 && isLoading) -1 else messageCount,
|
if (errors.all { it != null }) {
|
||||||
luckyNumber = if (luckyNumber == 0 && isLoading) -1 else luckyNumber
|
errors.firstOrNull()
|
||||||
|
} else null
|
||||||
|
},
|
||||||
|
attendancePercentage = DashboardItem.HorizontalGroup.Cell(
|
||||||
|
data = attendanceResource.dataOrNull?.calculatePercentage(),
|
||||||
|
error = attendanceResource.errorOrNull != null,
|
||||||
|
isLoading = attendanceResource is Resource.Loading,
|
||||||
|
),
|
||||||
|
unreadMessagesCount = DashboardItem.HorizontalGroup.Cell(
|
||||||
|
data = messageResource.dataOrNull?.count { it.unread },
|
||||||
|
error = messageResource.errorOrNull != null,
|
||||||
|
isLoading = messageResource is Resource.Loading,
|
||||||
|
),
|
||||||
|
luckyNumber = DashboardItem.HorizontalGroup.Cell(
|
||||||
|
data = luckyNumberResource.dataOrNull?.luckyNumber,
|
||||||
|
error = luckyNumberResource.errorOrNull != null,
|
||||||
|
isLoading = luckyNumberResource is Resource.Loading,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -280,11 +301,8 @@ class DashboardPresenter @Inject constructor(
|
|||||||
|
|
||||||
if (it.isLoading) {
|
if (it.isLoading) {
|
||||||
Timber.i("Loading horizontal group data started")
|
Timber.i("Loading horizontal group data started")
|
||||||
|
|
||||||
if (it.isFullDataLoaded) {
|
|
||||||
firstLoadedItemList += DashboardItem.Type.HORIZONTAL_GROUP
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
firstLoadedItemList += DashboardItem.Type.HORIZONTAL_GROUP
|
||||||
Timber.i("Loading horizontal group result: Success")
|
Timber.i("Loading horizontal group result: Success")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,81 +171,105 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
|
|||||||
position: Int
|
position: Int
|
||||||
) {
|
) {
|
||||||
val item = items[position] as DashboardItem.HorizontalGroup
|
val item = items[position] as DashboardItem.HorizontalGroup
|
||||||
val unreadMessagesCount = item.unreadMessagesCount
|
|
||||||
val attendancePercentage = item.attendancePercentage
|
|
||||||
val luckyNumber = item.luckyNumber
|
|
||||||
val error = item.error
|
|
||||||
val isLoading = item.isLoading
|
|
||||||
val binding = horizontalGroupViewHolder.binding
|
|
||||||
val context = binding.root.context
|
|
||||||
val isLoadingVisible =
|
val isLoadingVisible =
|
||||||
(isLoading && !item.isDataLoaded) || (isLoading && !item.isFullDataLoaded)
|
(item.isLoading && !item.isDataLoaded) || (item.isLoading && !item.isFullDataLoaded)
|
||||||
|
val isWideErrorShow = isLoadingVisible || item.error != null
|
||||||
|
|
||||||
|
with(horizontalGroupViewHolder.binding) {
|
||||||
|
dashboardHorizontalGroupItemInfoContainer.isVisible = isWideErrorShow
|
||||||
|
dashboardHorizontalGroupItemInfoProgress.isVisible = isLoadingVisible
|
||||||
|
dashboardHorizontalGroupItemInfoErrorText.isVisible = item.error != null
|
||||||
|
|
||||||
|
bindLuckyNumber(item, isWideErrorShow)
|
||||||
|
bindMessages(item, isWideErrorShow)
|
||||||
|
bindAttendance(item, isWideErrorShow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ItemDashboardHorizontalGroupBinding.bindLuckyNumber(
|
||||||
|
item: DashboardItem.HorizontalGroup,
|
||||||
|
isWideErrorShow: Boolean
|
||||||
|
) {
|
||||||
|
with(dashboardHorizontalGroupItemLuckyValue) {
|
||||||
|
isVisible = item.luckyNumber?.error != true
|
||||||
|
text = if (item.luckyNumber?.data == 0) {
|
||||||
|
context.getString(R.string.dashboard_horizontal_group_no_data)
|
||||||
|
} else item.luckyNumber?.data?.toString()
|
||||||
|
}
|
||||||
|
dashboardHorizontalGroupItemLuckyError.isVisible = item.luckyNumber?.error == true
|
||||||
|
with(dashboardHorizontalGroupItemLuckyContainer) {
|
||||||
|
isVisible = item.luckyNumber?.isHidden == false && !isWideErrorShow
|
||||||
|
setOnClickListener { onLuckyNumberTileClickListener() }
|
||||||
|
|
||||||
|
val isAttendanceHidden = item.attendancePercentage?.isHidden == true
|
||||||
|
val isMessagesHidden = item.unreadMessagesCount?.isHidden == true
|
||||||
|
val isLuckyNumberHidden = item.luckyNumber?.isHidden == true
|
||||||
|
|
||||||
|
updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||||
|
updateMarginsRelative(
|
||||||
|
end = if (isAttendanceHidden && isMessagesHidden && !isLuckyNumberHidden) {
|
||||||
|
0
|
||||||
|
} else context.dpToPx(8f).toInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ItemDashboardHorizontalGroupBinding.bindMessages(
|
||||||
|
item: DashboardItem.HorizontalGroup,
|
||||||
|
isWideErrorShow: Boolean
|
||||||
|
) {
|
||||||
|
dashboardHorizontalGroupItemMessageError.isVisible = item.unreadMessagesCount?.error == true
|
||||||
|
with(dashboardHorizontalGroupItemMessageValue) {
|
||||||
|
isVisible = item.unreadMessagesCount?.error != true
|
||||||
|
text = item.unreadMessagesCount?.data.toString()
|
||||||
|
}
|
||||||
|
with(dashboardHorizontalGroupItemMessageContainer) {
|
||||||
|
isVisible = item.unreadMessagesCount?.isHidden == false && !isWideErrorShow
|
||||||
|
setOnClickListener { onMessageTileClickListener() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ItemDashboardHorizontalGroupBinding.bindAttendance(
|
||||||
|
item: DashboardItem.HorizontalGroup,
|
||||||
|
isWideErrorShow: Boolean
|
||||||
|
) {
|
||||||
|
val attendancePercentage = item.attendancePercentage?.data
|
||||||
val attendanceColor = when {
|
val attendanceColor = when {
|
||||||
attendancePercentage == null || attendancePercentage == .0 -> {
|
attendancePercentage == null || attendancePercentage == .0 -> {
|
||||||
context.getThemeAttrColor(R.attr.colorOnSurface)
|
root.context.getThemeAttrColor(R.attr.colorOnSurface)
|
||||||
}
|
}
|
||||||
attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> {
|
attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> {
|
||||||
context.getThemeAttrColor(R.attr.colorPrimary)
|
root.context.getThemeAttrColor(R.attr.colorPrimary)
|
||||||
}
|
}
|
||||||
attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> {
|
attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> {
|
||||||
context.getThemeAttrColor(R.attr.colorTimetableChange)
|
root.context.getThemeAttrColor(R.attr.colorTimetableChange)
|
||||||
}
|
}
|
||||||
else -> context.getThemeAttrColor(R.attr.colorOnSurface)
|
else -> root.context.getThemeAttrColor(R.attr.colorOnSurface)
|
||||||
}
|
}
|
||||||
val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) {
|
val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) {
|
||||||
context.getString(R.string.dashboard_horizontal_group_no_data)
|
root.context.getString(R.string.dashboard_horizontal_group_no_data)
|
||||||
} else {
|
} else {
|
||||||
"%.2f%%".format(attendancePercentage)
|
"%.2f%%".format(attendancePercentage)
|
||||||
}
|
}
|
||||||
|
|
||||||
with(binding.dashboardHorizontalGroupItemAttendanceValue) {
|
dashboardHorizontalGroupItemAttendanceError.isVisible =
|
||||||
|
item.attendancePercentage?.error == true
|
||||||
|
with(dashboardHorizontalGroupItemAttendanceValue) {
|
||||||
|
isVisible = item.attendancePercentage?.error != true
|
||||||
text = attendanceString
|
text = attendanceString
|
||||||
setTextColor(attendanceColor)
|
setTextColor(attendanceColor)
|
||||||
}
|
}
|
||||||
|
with(dashboardHorizontalGroupItemAttendanceContainer) {
|
||||||
with(binding) {
|
isVisible = item.attendancePercentage?.isHidden == false && !isWideErrorShow
|
||||||
dashboardHorizontalGroupItemMessageValue.text = unreadMessagesCount.toString()
|
setOnClickListener { onAttendanceTileClickListener() }
|
||||||
dashboardHorizontalGroupItemLuckyValue.text = if (luckyNumber == 0) {
|
updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||||
context.getString(R.string.dashboard_horizontal_group_no_data)
|
matchConstraintPercentWidth = when {
|
||||||
} else luckyNumber?.toString()
|
item.luckyNumber?.isHidden == true && item.unreadMessagesCount?.isHidden == true -> 1.0f
|
||||||
|
item.luckyNumber?.isHidden == true || item.unreadMessagesCount?.isHidden == true -> 0.5f
|
||||||
dashboardHorizontalGroupItemInfoContainer.isVisible = error != null || isLoadingVisible
|
else -> 0.4f
|
||||||
dashboardHorizontalGroupItemInfoProgress.isVisible = isLoadingVisible
|
|
||||||
dashboardHorizontalGroupItemInfoErrorText.isVisible = error != null
|
|
||||||
|
|
||||||
with(dashboardHorizontalGroupItemLuckyContainer) {
|
|
||||||
isVisible = luckyNumber != null && luckyNumber != -1 && !isLoadingVisible
|
|
||||||
setOnClickListener { onLuckyNumberTileClickListener() }
|
|
||||||
|
|
||||||
updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
|
||||||
updateMarginsRelative(
|
|
||||||
end = if (attendancePercentage == null && unreadMessagesCount == null && luckyNumber != null) {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
context.dpToPx(8f).toInt()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
with(dashboardHorizontalGroupItemAttendanceContainer) {
|
|
||||||
isVisible =
|
|
||||||
attendancePercentage != null && attendancePercentage != -1.0 && !isLoadingVisible
|
|
||||||
updateLayoutParams<ConstraintLayout.LayoutParams> {
|
|
||||||
matchConstraintPercentWidth = when {
|
|
||||||
luckyNumber == null && unreadMessagesCount == null -> 1.0f
|
|
||||||
luckyNumber == null || unreadMessagesCount == null -> 0.5f
|
|
||||||
else -> 0.4f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setOnClickListener { onAttendanceTileClickListener() }
|
|
||||||
}
|
|
||||||
|
|
||||||
with(dashboardHorizontalGroupItemMessageContainer) {
|
|
||||||
isVisible =
|
|
||||||
unreadMessagesCount != null && unreadMessagesCount != -1 && !isLoadingVisible
|
|
||||||
setOnClickListener { onMessageTileClickListener() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,11 @@ package io.github.wulkanowy.utils
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.graphics.*
|
import android.graphics.*
|
||||||
import android.text.TextPaint
|
import android.text.TextPaint
|
||||||
import android.util.DisplayMetrics.DENSITY_DEFAULT
|
import android.util.DisplayMetrics.DENSITY_DEFAULT
|
||||||
|
import android.widget.ImageView
|
||||||
import androidx.annotation.*
|
import androidx.annotation.*
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
@ -12,6 +14,7 @@ import androidx.core.graphics.applyCanvas
|
|||||||
import androidx.core.graphics.drawable.RoundedBitmapDrawable
|
import androidx.core.graphics.drawable.RoundedBitmapDrawable
|
||||||
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
|
||||||
import androidx.core.graphics.drawable.toBitmap
|
import androidx.core.graphics.drawable.toBitmap
|
||||||
|
import androidx.core.widget.ImageViewCompat
|
||||||
|
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
@ -85,3 +88,7 @@ fun Context.createNameInitialsDrawable(
|
|||||||
return RoundedBitmapDrawableFactory.create(this.resources, bitmap)
|
return RoundedBitmapDrawableFactory.create(this.resources, bitmap)
|
||||||
.apply { isCircular = true }
|
.apply { isCircular = true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun ImageView.setTint(@ColorInt color: Int) {
|
||||||
|
ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
|
||||||
|
}
|
||||||
|
9
app/src/main/res/drawable/ic_error_filled.xml
Normal file
9
app/src/main/res/drawable/ic_error_filled.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"
|
||||||
|
android:fillColor="#000000"/>
|
||||||
|
</vector>
|
@ -37,9 +37,25 @@
|
|||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_goneMarginEnd="16dp"
|
||||||
app:tint="?colorOnSurface"
|
app:tint="?colorOnSurface"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dashboard_horizontal_group_item_lucky_error"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_marginEnd="-4dp"
|
||||||
|
android:layout_marginBottom="-4dp"
|
||||||
|
android:background="@drawable/ic_circle"
|
||||||
|
android:backgroundTint="?attr/colorSurface"
|
||||||
|
android:contentDescription="@string/error_unknown"
|
||||||
|
android:src="@drawable/ic_error_filled"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/dashboard_horizontal_group_item_lucky_icon"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/dashboard_horizontal_group_item_lucky_icon"
|
||||||
|
app:tint="?colorError"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dashboard_horizontal_group_item_lucky_value"
|
android:id="@+id/dashboard_horizontal_group_item_lucky_value"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -89,9 +105,25 @@
|
|||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_goneMarginEnd="16dp"
|
||||||
app:tint="?colorOnSurface"
|
app:tint="?colorOnSurface"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dashboard_horizontal_group_item_message_error"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_marginEnd="-4dp"
|
||||||
|
android:layout_marginBottom="-4dp"
|
||||||
|
android:background="@drawable/ic_circle"
|
||||||
|
android:backgroundTint="?attr/colorSurface"
|
||||||
|
android:contentDescription="@string/error_unknown"
|
||||||
|
android:src="@drawable/ic_error_filled"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/dashboard_horizontal_group_item_message_icon"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/dashboard_horizontal_group_item_message_icon"
|
||||||
|
app:tint="?colorError"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dashboard_horizontal_group_item_message_value"
|
android:id="@+id/dashboard_horizontal_group_item_message_value"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@ -106,7 +138,8 @@
|
|||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/dashboard_horizontal_group_item_message_icon"
|
app:layout_constraintStart_toEndOf="@id/dashboard_horizontal_group_item_message_icon"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:text="16" />
|
tools:text="16"
|
||||||
|
tools:visibility="visible" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
@ -145,9 +178,25 @@
|
|||||||
app:layout_constraintHorizontal_chainStyle="packed"
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_goneMarginEnd="16dp"
|
||||||
app:tint="?colorOnSurface"
|
app:tint="?colorOnSurface"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/dashboard_horizontal_group_item_attendance_error"
|
||||||
|
android:layout_width="18dp"
|
||||||
|
android:layout_height="18dp"
|
||||||
|
android:layout_marginEnd="-4dp"
|
||||||
|
android:layout_marginBottom="-4dp"
|
||||||
|
android:background="@drawable/ic_circle"
|
||||||
|
android:backgroundTint="?attr/colorSurface"
|
||||||
|
android:contentDescription="@string/error_unknown"
|
||||||
|
android:src="@drawable/ic_error_filled"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/dashboard_horizontal_group_item_attendance_icon"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/dashboard_horizontal_group_item_attendance_icon"
|
||||||
|
app:tint="?colorError"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dashboard_horizontal_group_item_attendance_value"
|
android:id="@+id/dashboard_horizontal_group_item_attendance_value"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
Loading…
Reference in New Issue
Block a user