forked from github/wulkanowy-mirror
Add school announcements (#1323)
This commit is contained in:
@ -9,6 +9,7 @@ import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.databinding.FragmentMoreBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
|
||||
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
|
||||
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
|
||||
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
@ -56,6 +57,9 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
|
||||
override val conferencesRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.conferences_title) to getCompatDrawable(R.drawable.ic_more_conferences) }
|
||||
|
||||
override val schoolAnnouncementRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.school_announcement_title) to getCompatDrawable(R.drawable.ic_all_about) }
|
||||
|
||||
override val schoolAndTeachersRes: Pair<String, Drawable?>?
|
||||
get() = context?.run { getString(R.string.schoolandteachers_title) to getCompatDrawable((R.drawable.ic_more_schoolandteachers)) }
|
||||
|
||||
@ -108,6 +112,10 @@ class MoreFragment : BaseFragment<FragmentMoreBinding>(R.layout.fragment_more),
|
||||
(activity as? MainActivity)?.pushView(MobileDeviceFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openSchoolAnnouncementView() {
|
||||
(activity as? MainActivity)?.pushView(SchoolAnnouncementFragment.newInstance())
|
||||
}
|
||||
|
||||
override fun openConferencesView() {
|
||||
(activity as? MainActivity)?.pushView(ConferenceFragment.newInstance())
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class MorePresenter @Inject constructor(
|
||||
luckyNumberRes?.first -> openLuckyNumberView()
|
||||
mobileDevicesRes?.first -> openMobileDevicesView()
|
||||
conferencesRes?.first -> openConferencesView()
|
||||
schoolAnnouncementRes?.first -> openSchoolAnnouncementView()
|
||||
schoolAndTeachersRes?.first -> openSchoolAndTeachersView()
|
||||
settingsRes?.first -> openSettingsView()
|
||||
}
|
||||
@ -49,6 +50,7 @@ class MorePresenter @Inject constructor(
|
||||
luckyNumberRes,
|
||||
mobileDevicesRes,
|
||||
conferencesRes,
|
||||
schoolAnnouncementRes,
|
||||
schoolAndTeachersRes,
|
||||
settingsRes
|
||||
))
|
||||
|
@ -17,6 +17,8 @@ interface MoreView : BaseView {
|
||||
|
||||
val conferencesRes: Pair<String, Drawable?>?
|
||||
|
||||
val schoolAnnouncementRes: Pair<String, Drawable?>?
|
||||
|
||||
val schoolAndTeachersRes: Pair<String, Drawable?>?
|
||||
|
||||
val settingsRes: Pair<String, Drawable?>?
|
||||
@ -39,6 +41,8 @@ interface MoreView : BaseView {
|
||||
|
||||
fun openMobileDevicesView()
|
||||
|
||||
fun openSchoolAnnouncementView()
|
||||
|
||||
fun openConferencesView()
|
||||
|
||||
fun openSchoolAndTeachersView()
|
||||
|
@ -0,0 +1,37 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolannouncement
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||
import io.github.wulkanowy.databinding.ItemSchoolAnnouncementBinding
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import javax.inject.Inject
|
||||
|
||||
class SchoolAnnouncementAdapter @Inject constructor() :
|
||||
RecyclerView.Adapter<SchoolAnnouncementAdapter.ViewHolder>() {
|
||||
|
||||
var items = emptyList<SchoolAnnouncement>()
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
|
||||
ItemSchoolAnnouncementBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
)
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
|
||||
with(holder.binding) {
|
||||
schoolAnnouncementItemDate.text = item.date.toFormattedString()
|
||||
schoolAnnouncementItemType.text = item.subject
|
||||
schoolAnnouncementItemContent.text = HtmlCompat.fromHtml(
|
||||
item.content, HtmlCompat.FROM_HTML_MODE_COMPACT
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ViewHolder(val binding: ItemSchoolAnnouncementBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolannouncement
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||
import io.github.wulkanowy.databinding.FragmentSchoolAnnouncementBinding
|
||||
import io.github.wulkanowy.ui.base.BaseFragment
|
||||
import io.github.wulkanowy.ui.modules.main.MainView
|
||||
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
|
||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class SchoolAnnouncementFragment :
|
||||
BaseFragment<FragmentSchoolAnnouncementBinding>(R.layout.fragment_school_announcement),
|
||||
SchoolAnnouncementView, MainView.TitledView {
|
||||
|
||||
@Inject
|
||||
lateinit var presenter: SchoolAnnouncementPresenter
|
||||
|
||||
@Inject
|
||||
lateinit var schoolAnnouncementAdapter: SchoolAnnouncementAdapter
|
||||
|
||||
companion object {
|
||||
fun newInstance() = SchoolAnnouncementFragment()
|
||||
}
|
||||
|
||||
override val titleStringId: Int
|
||||
get() = R.string.school_announcement_title
|
||||
|
||||
override val isViewEmpty: Boolean
|
||||
get() = schoolAnnouncementAdapter.items.isEmpty()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentSchoolAnnouncementBinding.bind(view)
|
||||
presenter.onAttachView(this)
|
||||
}
|
||||
|
||||
override fun initView() {
|
||||
with(binding.directorInformationRecycler) {
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
adapter = schoolAnnouncementAdapter
|
||||
addItemDecoration(DividerItemDecoration(context))
|
||||
}
|
||||
with(binding) {
|
||||
directorInformationSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
|
||||
directorInformationSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary))
|
||||
directorInformationSwipe.setProgressBackgroundColorSchemeColor(
|
||||
requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)
|
||||
)
|
||||
directorInformationErrorRetry.setOnClickListener { presenter.onRetry() }
|
||||
directorInformationErrorDetails.setOnClickListener { presenter.onDetailsClick() }
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateData(data: List<SchoolAnnouncement>) {
|
||||
with(schoolAnnouncementAdapter) {
|
||||
items = data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearData() {
|
||||
with(schoolAnnouncementAdapter) {
|
||||
items = listOf()
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun showEmpty(show: Boolean) {
|
||||
binding.directorInformationEmpty.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showErrorView(show: Boolean) {
|
||||
binding.directorInformationError.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun setErrorDetails(message: String) {
|
||||
binding.directorInformationErrorMessage.text = message
|
||||
}
|
||||
|
||||
override fun showProgress(show: Boolean) {
|
||||
binding.directorInformationProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun enableSwipe(enable: Boolean) {
|
||||
binding.directorInformationSwipe.isEnabled = enable
|
||||
}
|
||||
|
||||
override fun showContent(show: Boolean) {
|
||||
binding.directorInformationRecycler.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
override fun showRefresh(show: Boolean) {
|
||||
binding.directorInformationSwipe.isRefreshing = show
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
presenter.onDetachView()
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolannouncement
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
|
||||
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.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class SchoolAnnouncementPresenter @Inject constructor(
|
||||
errorHandler: ErrorHandler,
|
||||
studentRepository: StudentRepository,
|
||||
private val analytics: AnalyticsHelper,
|
||||
private val schoolAnnouncementRepository: SchoolAnnouncementRepository,
|
||||
) : BasePresenter<SchoolAnnouncementView>(errorHandler, studentRepository) {
|
||||
|
||||
private lateinit var lastError: Throwable
|
||||
|
||||
override fun onAttachView(view: SchoolAnnouncementView) {
|
||||
super.onAttachView(view)
|
||||
view.initView()
|
||||
Timber.i("School announcement view was initialized")
|
||||
errorHandler.showErrorMessage = ::showErrorViewOnError
|
||||
loadData()
|
||||
}
|
||||
|
||||
fun onSwipeRefresh() {
|
||||
Timber.i("Force refreshing the School announcement")
|
||||
loadData(true)
|
||||
}
|
||||
|
||||
fun onRetry() {
|
||||
view?.run {
|
||||
showErrorView(false)
|
||||
showProgress(true)
|
||||
}
|
||||
loadData(true)
|
||||
}
|
||||
|
||||
fun onDetailsClick() {
|
||||
view?.showErrorDetailsDialog(lastError)
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading School announcement data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading School announcement result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.sortedByDescending { item -> item.date })
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.data.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_school_announcement",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading School announcement result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
view?.run {
|
||||
if (isViewEmpty) {
|
||||
lastError = error
|
||||
setErrorDetails(message)
|
||||
showErrorView(true)
|
||||
showEmpty(false)
|
||||
} else showError(message, error)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolannouncement
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||
import io.github.wulkanowy.ui.base.BaseView
|
||||
|
||||
interface SchoolAnnouncementView : BaseView {
|
||||
|
||||
val isViewEmpty: Boolean
|
||||
|
||||
fun initView()
|
||||
|
||||
fun updateData(data: List<SchoolAnnouncement>)
|
||||
|
||||
fun clearData()
|
||||
|
||||
fun showEmpty(show: Boolean)
|
||||
|
||||
fun showErrorView(show: Boolean)
|
||||
|
||||
fun setErrorDetails(message: String)
|
||||
|
||||
fun showProgress(show: Boolean)
|
||||
|
||||
fun enableSwipe(enable: Boolean)
|
||||
|
||||
fun showContent(show: Boolean)
|
||||
|
||||
fun showRefresh(show: Boolean)
|
||||
}
|
Reference in New Issue
Block a user