forked from github/wulkanowy-mirror
Add avatars (#1146)
This commit is contained in:
@ -1,16 +1,17 @@
|
||||
package io.github.wulkanowy.ui.modules.account
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.PorterDuff
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.databinding.HeaderAccountBinding
|
||||
import io.github.wulkanowy.databinding.ItemAccountBinding
|
||||
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
import io.github.wulkanowy.utils.nickOrName
|
||||
import javax.inject.Inject
|
||||
@ -72,9 +73,13 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.V
|
||||
binding: ItemAccountBinding,
|
||||
studentWithSemesters: StudentWithSemesters
|
||||
) {
|
||||
val context = binding.root.context
|
||||
val student = studentWithSemesters.student
|
||||
val semesters = studentWithSemesters.semesters
|
||||
val diary = semesters.maxByOrNull { it.semesterId }
|
||||
val avatar = context.createNameInitialsDrawable(student.nickOrName, student.avatarColor)
|
||||
val checkBackgroundColor =
|
||||
context.getThemeAttrColor(if (isAccountQuickDialogMode) R.attr.colorBackgroundFloating else R.attr.colorSurface)
|
||||
val isDuplicatedStudent = items.filter {
|
||||
if (it.value !is StudentWithSemesters) return@filter false
|
||||
val studentToCompare = it.value.student
|
||||
@ -87,15 +92,17 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.V
|
||||
with(binding) {
|
||||
accountItemName.text = "${student.nickOrName} ${diary?.diaryName.orEmpty()}"
|
||||
accountItemSchool.text = studentWithSemesters.student.schoolName
|
||||
accountItemAccountType.setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student)
|
||||
accountItemAccountType.visibility = if (isDuplicatedStudent) VISIBLE else GONE
|
||||
accountItemImage.setImageDrawable(avatar)
|
||||
|
||||
with(accountItemImage) {
|
||||
val colorImage =
|
||||
if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
||||
else context.getThemeAttrColor(R.attr.colorOnSurface, 153)
|
||||
with(accountItemAccountType) {
|
||||
setText(if (student.isParent) R.string.account_type_parent else R.string.account_type_student)
|
||||
isVisible = isDuplicatedStudent
|
||||
}
|
||||
|
||||
setColorFilter(colorImage, PorterDuff.Mode.SRC_IN)
|
||||
with(accountItemCheck) {
|
||||
isVisible = student.isCurrent
|
||||
borderColor = checkBackgroundColor
|
||||
circleColor = checkBackgroundColor
|
||||
}
|
||||
|
||||
root.setOnClickListener { onClickListener(studentWithSemesters) }
|
||||
|
@ -36,23 +36,20 @@ class AccountFragment : BaseFragment<FragmentAccountBinding>(R.layout.fragment_a
|
||||
|
||||
override var subtitleString = ""
|
||||
|
||||
override val isViewEmpty get() = accountAdapter.items.isEmpty()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding = FragmentAccountBinding.bind(view)
|
||||
presenter.onAttachView(this)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
binding.accountErrorRetry.setOnClickListener { presenter.onRetry() }
|
||||
binding.accountErrorDetails.setOnClickListener { presenter.onDetailsClick() }
|
||||
|
||||
binding.accountRecycler.apply {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = accountAdapter
|
||||
@ -60,9 +57,7 @@ class AccountFragment : BaseFragment<FragmentAccountBinding>(R.layout.fragment_a
|
||||
|
||||
accountAdapter.onClickListener = presenter::onItemSelected
|
||||
|
||||
with(binding) {
|
||||
accountAdd.setOnClickListener { presenter.onAddSelected() }
|
||||
}
|
||||
binding.accountAdd.setOnClickListener { presenter.onAddSelected() }
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@ -84,28 +79,7 @@ class AccountFragment : BaseFragment<FragmentAccountBinding>(R.layout.fragment_a
|
||||
|
||||
override fun openAccountDetailsView(studentWithSemesters: StudentWithSemesters) {
|
||||
(activity as? MainActivity)?.pushView(
|
||||
AccountDetailsFragment.newInstance(
|
||||
studentWithSemesters
|
||||
)
|
||||
AccountDetailsFragment.newInstance(studentWithSemesters)
|
||||
)
|
||||
}
|
||||
|
||||
override fun showErrorView(show: Boolean) {
|
||||
binding.accountError.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun setErrorDetails(message: String) {
|
||||
binding.accountErrorMessage.text = message
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
binding.accountProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
with(binding) {
|
||||
accountRecycler.visibility = if (show) View.VISIBLE else View.GONE
|
||||
accountAdd.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
@ -16,28 +15,13 @@ class AccountPresenter @Inject constructor(
|
||||
studentRepository: StudentRepository,
|
||||
) : BasePresenter<AccountView>(errorHandler, studentRepository) {
|
||||
|
||||
private lateinit var lastError: Throwable
|
||||
|
||||
override fun onAttachView(view: AccountView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
Timber.i("Account view was initialized")
|
||||
errorHandler.showErrorMessage = ::showErrorViewOnError
|
||||
loadData()
|
||||
}
|
||||
|
||||
fun onRetry() {
|
||||
view?.run {
|
||||
showErrorView(false)
|
||||
showProgress(true)
|
||||
}
|
||||
loadData()
|
||||
}
|
||||
|
||||
fun onDetailsClick() {
|
||||
view?.showErrorDetailsDialog(lastError)
|
||||
}
|
||||
|
||||
fun onAddSelected() {
|
||||
Timber.i("Select add account")
|
||||
view?.openLoginView()
|
||||
@ -47,6 +31,24 @@ class AccountPresenter @Inject constructor(
|
||||
view?.openAccountDetailsView(studentWithSemesters)
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading account data started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading account result: Success")
|
||||
view?.updateData(createAccountItems(it.data!!))
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading account result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
.launch("load")
|
||||
}
|
||||
|
||||
private fun createAccountItems(items: List<StudentWithSemesters>): List<AccountItem<*>> {
|
||||
return items.groupBy {
|
||||
Account("${it.student.userName} (${it.student.email})", it.student.isParent)
|
||||
@ -60,45 +62,4 @@ class AccountPresenter @Inject constructor(
|
||||
}
|
||||
.flatten()
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading account data started")
|
||||
view?.run {
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading account result: Success")
|
||||
view?.updateData(createAccountItems(it.data!!))
|
||||
view?.run {
|
||||
showContent(true)
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading account result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
.afterLoading { view?.showProgress(false) }
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
view?.run {
|
||||
if (isViewEmpty) {
|
||||
lastError = error
|
||||
setErrorDetails(message)
|
||||
showErrorView(true)
|
||||
showContent(false)
|
||||
showProgress(false)
|
||||
} else showError(message, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface AccountView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<AccountItem<*>>)
|
||||
@ -14,13 +12,4 @@ interface AccountView : BaseView {
|
||||
fun openLoginView()
|
||||
|
||||
fun openAccountDetailsView(studentWithSemesters: StudentWithSemesters)
|
||||
|
||||
fun showErrorView(show: Boolean)
|
||||
|
||||
fun setErrorDetails(message: String)
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.get
|
||||
import androidx.core.view.isVisible
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
@ -18,6 +19,7 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoFragment
|
||||
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
|
||||
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||
import io.github.wulkanowy.utils.nickOrName
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -88,8 +90,15 @@ class AccountDetailsFragment :
|
||||
|
||||
override fun showAccountData(student: Student) {
|
||||
with(binding) {
|
||||
accountDetailsCheck.isVisible = student.isCurrent
|
||||
accountDetailsName.text = student.nickOrName
|
||||
accountDetailsSchool.text = student.schoolName
|
||||
accountDetailsAvatar.setImageDrawable(
|
||||
requireContext().createNameInitialsDrawable(
|
||||
student.nickOrName,
|
||||
student.avatarColor
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
private val syncManager: SyncManager
|
||||
) : BasePresenter<AccountDetailsView>(errorHandler, studentRepository) {
|
||||
|
||||
private lateinit var studentWithSemesters: StudentWithSemesters
|
||||
private var studentWithSemesters: StudentWithSemesters? = null
|
||||
|
||||
private lateinit var lastError: Throwable
|
||||
|
||||
@ -69,10 +69,10 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading account details view result: Success")
|
||||
studentWithSemesters = it.data!!
|
||||
studentWithSemesters = it.data
|
||||
view?.run {
|
||||
showAccountData(studentWithSemesters.student)
|
||||
enableSelectStudentButton(!studentWithSemesters.student.isCurrent)
|
||||
showAccountData(studentWithSemesters!!.student)
|
||||
enableSelectStudentButton(!studentWithSemesters!!.student.isCurrent)
|
||||
showContent(true)
|
||||
showErrorView(false)
|
||||
}
|
||||
@ -88,17 +88,23 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onAccountEditSelected() {
|
||||
view?.showAccountEditDetailsDialog(studentWithSemesters.student)
|
||||
studentWithSemesters?.let {
|
||||
view?.showAccountEditDetailsDialog(it.student)
|
||||
}
|
||||
}
|
||||
|
||||
fun onStudentInfoSelected(infoType: StudentInfoView.Type) {
|
||||
view?.openStudentInfoView(infoType, studentWithSemesters)
|
||||
studentWithSemesters?.let {
|
||||
view?.openStudentInfoView(infoType, it)
|
||||
}
|
||||
}
|
||||
|
||||
fun onStudentSelect() {
|
||||
Timber.i("Select student ${studentWithSemesters.student.id}")
|
||||
if (studentWithSemesters == null) return
|
||||
|
||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters) }
|
||||
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
||||
|
||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters!!) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to change a student")
|
||||
@ -122,8 +128,10 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onLogoutConfirm() {
|
||||
if (studentWithSemesters == null) return
|
||||
|
||||
flowWithResource {
|
||||
val studentToLogout = studentWithSemesters.student
|
||||
val studentToLogout = studentWithSemesters!!.student
|
||||
|
||||
studentRepository.logoutStudent(studentToLogout)
|
||||
val students = studentRepository.getSavedStudents(false)
|
||||
@ -143,7 +151,7 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
syncManager.stopSyncWorker()
|
||||
openClearLoginView()
|
||||
}
|
||||
studentWithSemesters.student.isCurrent -> {
|
||||
studentWithSemesters!!.student.isCurrent -> {
|
||||
Timber.i("Logout result: Logout student and switch to another")
|
||||
recreateMainView()
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
package io.github.wulkanowy.ui.modules.account.accountedit
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.graphics.drawable.RippleDrawable
|
||||
import android.graphics.drawable.StateListDrawable
|
||||
import android.os.Build
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.databinding.ItemAccountEditColorBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
class AccountEditColorAdapter @Inject constructor() :
|
||||
RecyclerView.Adapter<AccountEditColorAdapter.ViewHolder>() {
|
||||
|
||||
var items = listOf<Int>()
|
||||
|
||||
var selectedColor = 0
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
ItemAccountEditColorBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
)
|
||||
|
||||
@SuppressLint("RestrictedApi", "NewApi")
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
|
||||
with(holder.binding) {
|
||||
accountEditItemColor.setImageDrawable(GradientDrawable().apply {
|
||||
shape = GradientDrawable.OVAL
|
||||
setColor(item)
|
||||
})
|
||||
|
||||
accountEditItemColorContainer.foreground = item.createForegroundDrawable()
|
||||
accountEditCheck.isVisible = selectedColor == item
|
||||
|
||||
root.setOnClickListener {
|
||||
val oldSelectedPosition = items.indexOf(selectedColor)
|
||||
selectedColor = item
|
||||
|
||||
notifyItemChanged(oldSelectedPosition)
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.createForegroundDrawable(): Drawable =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val mask = GradientDrawable().apply {
|
||||
shape = GradientDrawable.OVAL
|
||||
setColor(Color.BLACK)
|
||||
}
|
||||
RippleDrawable(ColorStateList.valueOf(this.rippleColor), null, mask)
|
||||
} else {
|
||||
val foreground = StateListDrawable().apply {
|
||||
alpha = 80
|
||||
setEnterFadeDuration(250)
|
||||
setExitFadeDuration(250)
|
||||
}
|
||||
|
||||
val mask = GradientDrawable().apply {
|
||||
shape = GradientDrawable.OVAL
|
||||
setColor(this@createForegroundDrawable.rippleColor)
|
||||
}
|
||||
|
||||
foreground.apply {
|
||||
addState(intArrayOf(android.R.attr.state_pressed), mask)
|
||||
addState(intArrayOf(), ColorDrawable(Color.TRANSPARENT))
|
||||
}
|
||||
}
|
||||
|
||||
private inline val Int.rippleColor: Int
|
||||
get() {
|
||||
val hsv = FloatArray(3)
|
||||
Color.colorToHSV(this, hsv)
|
||||
hsv[2] = hsv[2] * 0.5f
|
||||
return Color.HSVToColor(hsv)
|
||||
}
|
||||
|
||||
class ViewHolder(val binding: ItemAccountEditColorBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
}
|
@ -4,6 +4,7 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.databinding.DialogAccountEditBinding
|
||||
@ -16,6 +17,9 @@ class AccountEditDialog : BaseDialogFragment<DialogAccountEditBinding>(), Accoun
|
||||
@Inject
|
||||
lateinit var presenter: AccountEditPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var accountEditColorAdapter: AccountEditColorAdapter
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ARGUMENT_KEY = "student_with_semesters"
|
||||
@ -48,8 +52,30 @@ class AccountEditDialog : BaseDialogFragment<DialogAccountEditBinding>(), Accoun
|
||||
with(binding) {
|
||||
accountEditDetailsCancel.setOnClickListener { dismiss() }
|
||||
accountEditDetailsSave.setOnClickListener {
|
||||
presenter.changeStudentNick(binding.accountEditDetailsNickText.text.toString())
|
||||
presenter.changeStudentNickAndAvatar(
|
||||
binding.accountEditDetailsNickText.text.toString(),
|
||||
accountEditColorAdapter.selectedColor
|
||||
)
|
||||
}
|
||||
|
||||
with(binding.accountEditColors) {
|
||||
layoutManager = GridLayoutManager(context, 4)
|
||||
adapter = accountEditColorAdapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateSelectedColorData(color: Int) {
|
||||
with(accountEditColorAdapter) {
|
||||
selectedColor = color
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateColorsData(colors: List<Int>) {
|
||||
with(accountEditColorAdapter) {
|
||||
items = colors
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,11 @@ package io.github.wulkanowy.ui.modules.account.accountedit
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentNick
|
||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -13,12 +14,15 @@ import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class AccountEditPresenter @Inject constructor(
|
||||
private val appInfo: AppInfo,
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository
|
||||
) : BasePresenter<AccountEditView>(errorHandler, studentRepository) {
|
||||
|
||||
lateinit var student: Student
|
||||
|
||||
private val colors = appInfo.defaultColorsForAvatar.map { it.toInt() }
|
||||
|
||||
fun onAttachView(view: AccountEditView, student: Student) {
|
||||
super.onAttachView(view)
|
||||
this.student = student
|
||||
@ -28,27 +32,49 @@ class AccountEditPresenter @Inject constructor(
|
||||
showCurrentNick(student.nick.trim())
|
||||
}
|
||||
Timber.i("Account edit dialog view was initialized")
|
||||
loadData()
|
||||
|
||||
view.updateColorsData(colors)
|
||||
}
|
||||
|
||||
fun changeStudentNick(nick: String) {
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
studentRepository.getStudentById(student.id, false).avatarColor
|
||||
}.onEach { resource ->
|
||||
when (resource.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to load student")
|
||||
Status.SUCCESS -> {
|
||||
view?.updateSelectedColorData(resource.data?.toInt()!!)
|
||||
Timber.i("Attempt to load student: Success")
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Attempt to load student: An exception occurred")
|
||||
errorHandler.dispatch(resource.error!!)
|
||||
}
|
||||
}
|
||||
}.launch("load_data")
|
||||
}
|
||||
|
||||
fun changeStudentNickAndAvatar(nick: String, avatarColor: Int) {
|
||||
flowWithResource {
|
||||
val studentNick =
|
||||
StudentNick(nick = nick.trim()).apply { id = student.id }
|
||||
studentRepository.updateStudentNick(studentNick)
|
||||
StudentNickAndAvatar(nick = nick.trim(), avatarColor = avatarColor.toLong())
|
||||
.apply { id = student.id }
|
||||
studentRepository.updateStudentNickAndAvatar(studentNick)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to change a student nick")
|
||||
Status.LOADING -> Timber.i("Attempt to change a student nick and avatar")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Change a student nick result: Success")
|
||||
Timber.i("Change a student nick and avatar result: Success")
|
||||
view?.recreateMainView()
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Change a student result: An exception occurred")
|
||||
Timber.i("Change a student nick and avatar result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
.afterLoading { view?.popView() }
|
||||
.launch()
|
||||
.launch("update_student")
|
||||
}
|
||||
}
|
||||
|
@ -11,4 +11,8 @@ interface AccountEditView : BaseView {
|
||||
fun recreateMainView()
|
||||
|
||||
fun showCurrentNick(nick: String)
|
||||
|
||||
fun updateSelectedColorData(color: Int)
|
||||
|
||||
fun updateColorsData(colors: List<Int>)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.databinding.DialogAccountQuickBinding
|
||||
import io.github.wulkanowy.ui.base.BaseDialogFragment
|
||||
import io.github.wulkanowy.ui.modules.account.AccountAdapter
|
||||
@ -24,7 +25,15 @@ class AccountQuickDialog : BaseDialogFragment<DialogAccountQuickBinding>(), Acco
|
||||
lateinit var presenter: AccountQuickPresenter
|
||||
|
||||
companion object {
|
||||
fun newInstance() = AccountQuickDialog()
|
||||
|
||||
private const val STUDENTS_ARGUMENT_KEY = "students"
|
||||
|
||||
fun newInstance(studentsWithSemesters: List<StudentWithSemesters>) =
|
||||
AccountQuickDialog().apply {
|
||||
arguments = Bundle().apply {
|
||||
putSerializable(STUDENTS_ARGUMENT_KEY, studentsWithSemesters.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@ -38,8 +47,12 @@ class AccountQuickDialog : BaseDialogFragment<DialogAccountQuickBinding>(), Acco
|
||||
savedInstanceState: Bundle?
|
||||
) = DialogAccountQuickBinding.inflate(inflater).apply { binding = this }.root
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
presenter.onAttachView(this)
|
||||
val studentsWithSemesters =
|
||||
(requireArguments()[STUDENTS_ARGUMENT_KEY] as Array<StudentWithSemesters>).toList()
|
||||
|
||||
presenter.onAttachView(this, studentsWithSemesters)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
|
@ -17,11 +17,15 @@ class AccountQuickPresenter @Inject constructor(
|
||||
studentRepository: StudentRepository
|
||||
) : BasePresenter<AccountQuickView>(errorHandler, studentRepository) {
|
||||
|
||||
override fun onAttachView(view: AccountQuickView) {
|
||||
private lateinit var studentsWithSemesters: List<StudentWithSemesters>
|
||||
|
||||
fun onAttachView(view: AccountQuickView, studentsWithSemesters: List<StudentWithSemesters>) {
|
||||
super.onAttachView(view)
|
||||
this.studentsWithSemesters = studentsWithSemesters
|
||||
|
||||
view.initView()
|
||||
Timber.i("Account quick dialog view was initialized")
|
||||
loadData()
|
||||
view.updateData(createAccountItems(studentsWithSemesters))
|
||||
}
|
||||
|
||||
fun onManagerSelected() {
|
||||
@ -57,22 +61,6 @@ class AccountQuickPresenter @Inject constructor(
|
||||
.launch("switch")
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading account data started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading account result: Success")
|
||||
view?.updateData(createAccountItems(it.data!!))
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading account result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.launch()
|
||||
}
|
||||
|
||||
private fun createAccountItems(items: List<StudentWithSemesters>) = items.map {
|
||||
AccountItem(it, AccountItem.ViewType.ITEM)
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ import com.ncapdevi.fragnav.FragNavController
|
||||
import com.ncapdevi.fragnav.FragNavController.Companion.HIDE
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.databinding.ActivityMainBinding
|
||||
import io.github.wulkanowy.ui.base.BaseActivity
|
||||
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
|
||||
@ -43,8 +45,10 @@ import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.UpdateHelper
|
||||
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
||||
import io.github.wulkanowy.utils.dpToPx
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
import io.github.wulkanowy.utils.nickOrName
|
||||
import io.github.wulkanowy.utils.safelyPopFragments
|
||||
import io.github.wulkanowy.utils.setOnViewChangeListener
|
||||
import timber.log.Timber
|
||||
@ -65,6 +69,8 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
@Inject
|
||||
lateinit var appInfo: AppInfo
|
||||
|
||||
private var accountMenu: MenuItem? = null
|
||||
|
||||
private val overlayProvider by lazy { ElevationOverlayProvider(this) }
|
||||
|
||||
private val navController =
|
||||
@ -192,6 +198,9 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.action_menu_main, menu)
|
||||
accountMenu = menu?.findItem(R.id.mainMenuAccount)
|
||||
|
||||
presenter.onActionMenuCreated()
|
||||
return true
|
||||
}
|
||||
|
||||
@ -288,8 +297,8 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(show)
|
||||
}
|
||||
|
||||
override fun showAccountPicker() {
|
||||
navController.showDialogFragment(AccountQuickDialog.newInstance())
|
||||
override fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>) {
|
||||
navController.showDialogFragment(AccountQuickDialog.newInstance(studentWithSemesters))
|
||||
}
|
||||
|
||||
override fun showActionBarElevation(show: Boolean) {
|
||||
@ -323,6 +332,13 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
||||
presenter.onBackPressed { super.onBackPressed() }
|
||||
}
|
||||
|
||||
override fun showStudentAvatar(student: Student) {
|
||||
accountMenu?.run {
|
||||
icon = createNameInitialsDrawable(student.nickOrName, student.avatarColor, 0.44f)
|
||||
title = getString(R.string.main_account_picker)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
navController.onSaveInstanceState(outState)
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.main
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
@ -9,6 +11,8 @@ import io.github.wulkanowy.ui.modules.main.MainView.Section.GRADE
|
||||
import io.github.wulkanowy.ui.modules.main.MainView.Section.MESSAGE
|
||||
import io.github.wulkanowy.ui.modules.main.MainView.Section.SCHOOL
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -17,9 +21,11 @@ class MainPresenter @Inject constructor(
|
||||
studentRepository: StudentRepository,
|
||||
private val prefRepository: PreferencesRepository,
|
||||
private val syncManager: SyncManager,
|
||||
private val analytics: AnalyticsHelper
|
||||
private val analytics: AnalyticsHelper,
|
||||
) : BasePresenter<MainView>(errorHandler, studentRepository) {
|
||||
|
||||
var studentsWitSemesters: List<StudentWithSemesters>? = null
|
||||
|
||||
fun onAttachView(view: MainView, initMenu: MainView.Section?) {
|
||||
super.onAttachView(view)
|
||||
view.apply {
|
||||
@ -35,6 +41,28 @@ class MainPresenter @Inject constructor(
|
||||
analytics.logEvent("app_open", "destination" to initMenu?.name)
|
||||
}
|
||||
|
||||
fun onActionMenuCreated() {
|
||||
if (!studentsWitSemesters.isNullOrEmpty()) {
|
||||
showCurrentStudentAvatar()
|
||||
return
|
||||
}
|
||||
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
||||
.onEach { resource ->
|
||||
when (resource.status) {
|
||||
Status.LOADING -> Timber.i("Loading student avatar data started")
|
||||
Status.SUCCESS -> {
|
||||
studentsWitSemesters = resource.data
|
||||
showCurrentStudentAvatar()
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading student avatar result: An exception occurred")
|
||||
errorHandler.dispatch(resource.error!!)
|
||||
}
|
||||
}
|
||||
}.launch("avatar")
|
||||
}
|
||||
|
||||
fun onViewChange(section: MainView.Section?) {
|
||||
view?.apply {
|
||||
showActionBarElevation(section != GRADE && section != MESSAGE && section != SCHOOL)
|
||||
@ -48,8 +76,10 @@ class MainPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onAccountManagerSelected(): Boolean {
|
||||
if (studentsWitSemesters.isNullOrEmpty()) return true
|
||||
|
||||
Timber.i("Select account manager")
|
||||
view?.showAccountPicker()
|
||||
view?.showAccountPicker(studentsWitSemesters!!)
|
||||
return true
|
||||
}
|
||||
|
||||
@ -81,6 +111,13 @@ class MainPresenter @Inject constructor(
|
||||
} == true
|
||||
}
|
||||
|
||||
private fun showCurrentStudentAvatar() {
|
||||
val currentStudent =
|
||||
studentsWitSemesters!!.single { it.student.isCurrent }.student
|
||||
|
||||
view?.showStudentAvatar(currentStudent)
|
||||
}
|
||||
|
||||
private fun getProperViewIndexes(initMenu: MainView.Section?): Pair<Int, Int> {
|
||||
return when (initMenu?.id) {
|
||||
in 0..3 -> initMenu!!.id to -1
|
||||
|
@ -1,5 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.main
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface MainView : BaseView {
|
||||
@ -22,7 +24,7 @@ interface MainView : BaseView {
|
||||
|
||||
fun showHomeArrow(show: Boolean)
|
||||
|
||||
fun showAccountPicker()
|
||||
fun showAccountPicker(studentWithSemesters: List<StudentWithSemesters>)
|
||||
|
||||
fun showActionBarElevation(show: Boolean)
|
||||
|
||||
@ -36,6 +38,8 @@ interface MainView : BaseView {
|
||||
|
||||
fun popView(depth: Int = 1)
|
||||
|
||||
fun showStudentAvatar(student: Student)
|
||||
|
||||
interface MainChildView {
|
||||
|
||||
fun onFragmentReselected()
|
||||
|
Reference in New Issue
Block a user