Refactor notification destinations (#1709)

Co-authored-by: Rafał Borcz <RafalBO99@outlook.com>
This commit is contained in:
Michael
2022-01-28 13:43:56 +01:00
committed by GitHub
parent de9fcb9af9
commit daa7b54dab
24 changed files with 2578 additions and 189 deletions

View File

@ -1,6 +1,7 @@
package io.github.wulkanowy.ui.modules
import androidx.fragment.app.Fragment
import io.github.wulkanowy.data.serializers.LocalDateSerializer
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
import io.github.wulkanowy.ui.modules.dashboard.DashboardFragment
@ -14,18 +15,19 @@ import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import java.io.Serializable
import kotlinx.serialization.Serializable
import java.time.LocalDate
sealed interface Destination : Serializable {
@Serializable
sealed class Destination private constructor() : java.io.Serializable {
/*
Type in children classes have to be as getter to avoid null in enums
https://stackoverflow.com/questions/68866453/kotlin-enum-val-is-returning-null-despite-being-set-at-compile-time
*/
val type: Type
abstract val type: Type
val fragment: Fragment
abstract val fragment: Fragment
enum class Type(val defaultDestination: Destination) {
DASHBOARD(Dashboard),
@ -43,94 +45,84 @@ sealed interface Destination : Serializable {
MESSAGE(Message);
}
object Dashboard : Destination {
@Serializable
object Dashboard : Destination() {
override val type get() = Type.DASHBOARD
override val fragment get() = DashboardFragment.newInstance()
}
object Grade : Destination {
@Serializable
object Grade : Destination() {
override val type get() = Type.GRADE
override val fragment get() = GradeFragment.newInstance()
}
object Attendance : Destination {
@Serializable
object Attendance : Destination() {
override val type get() = Type.ATTENDANCE
override val fragment get() = AttendanceFragment.newInstance()
}
object Exam : Destination {
@Serializable
object Exam : Destination() {
override val type get() = Type.EXAM
override val fragment get() = ExamFragment.newInstance()
}
data class Timetable(val date: LocalDate? = null) : Destination {
@Serializable
data class Timetable(
@Serializable(with = LocalDateSerializer::class)
private val date: LocalDate? = null
) : Destination() {
override val type get() = Type.TIMETABLE
override val fragment get() = TimetableFragment.newInstance(date)
}
object Homework : Destination {
@Serializable
object Homework : Destination() {
override val type get() = Type.HOMEWORK
override val fragment get() = HomeworkFragment.newInstance()
}
object Note : Destination {
@Serializable
object Note : Destination() {
override val type get() = Type.NOTE
override val fragment get() = NoteFragment.newInstance()
}
object Conference : Destination {
@Serializable
object Conference : Destination() {
override val type get() = Type.CONFERENCE
override val fragment get() = ConferenceFragment.newInstance()
}
object SchoolAnnouncement : Destination {
@Serializable
object SchoolAnnouncement : Destination() {
override val type get() = Type.SCHOOL_ANNOUNCEMENT
override val fragment get() = SchoolAnnouncementFragment.newInstance()
}
object School : Destination {
@Serializable
object School : Destination() {
override val type get() = Type.SCHOOL
override val fragment get() = SchoolFragment.newInstance()
}
object LuckyNumber : Destination {
@Serializable
object LuckyNumber : Destination() {
override val type get() = Type.LUCKY_NUMBER
override val fragment get() = LuckyNumberFragment.newInstance()
}
object More : Destination {
@Serializable
object More : Destination() {
override val type get() = Type.MORE
override val fragment get() = MoreFragment.newInstance()
}
object Message : Destination {
@Serializable
object Message : Destination() {
override val type get() = Type.MESSAGE
override val fragment get() = MessageFragment.newInstance()
}
}
}

View File

@ -25,8 +25,8 @@ private fun generateTimetable(subject: String, room: String, roomOld: String) =
diaryId = 0,
date = LocalDate.now().minusDays(Random.nextLong(0, 8)),
number = 1,
start = Instant.now(),
end = Instant.now().plus(Duration.ofHours(1)),
start = Instant.now().plus(Duration.ofHours(1)),
end = Instant.now(),
subjectOld = "",
group = "",
room = room,

View File

@ -7,14 +7,13 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.data.db.entities.Notification
import io.github.wulkanowy.databinding.ItemNotificationsCenterBinding
import io.github.wulkanowy.services.sync.notifications.NotificationType
import io.github.wulkanowy.utils.toFormattedString
import javax.inject.Inject
class NotificationsCenterAdapter @Inject constructor() :
ListAdapter<Notification, NotificationsCenterAdapter.ViewHolder>(DiffUtilCallback()) {
var onItemClickListener: (NotificationType) -> Unit = {}
var onItemClickListener: (Notification) -> Unit = {}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
ItemNotificationsCenterBinding.inflate(LayoutInflater.from(parent.context), parent, false)
@ -29,7 +28,7 @@ class NotificationsCenterAdapter @Inject constructor() :
notificationsCenterItemDate.text = item.date.toFormattedString("HH:mm, d MMM")
notificationsCenterItemIcon.setImageResource(item.type.icon)
root.setOnClickListener { onItemClickListener(item.type) }
root.setOnClickListener { onItemClickListener(item) }
}
}

View File

@ -3,26 +3,14 @@ package io.github.wulkanowy.ui.modules.notificationscenter
import android.os.Bundle
import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Notification
import io.github.wulkanowy.databinding.FragmentNotificationsCenterBinding
import io.github.wulkanowy.services.sync.notifications.NotificationType
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
import io.github.wulkanowy.ui.modules.exam.ExamFragment
import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.homework.HomeworkFragment
import io.github.wulkanowy.ui.modules.luckynumber.LuckyNumberFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.note.NoteFragment
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
import javax.inject.Inject
@AndroidEntryPoint
@ -54,9 +42,8 @@ class NotificationsCenterFragment :
}
override fun initView() {
notificationsCenterAdapter.onItemClickListener = { notificationType ->
notificationType.toDestinationFragment()
?.let { (requireActivity() as MainActivity).pushView(it) }
notificationsCenterAdapter.onItemClickListener = { notification ->
(requireActivity() as MainActivity).pushView(notification.destination.fragment)
}
with(binding.notificationsCenterRecycler) {
@ -93,20 +80,4 @@ class NotificationsCenterFragment :
presenter.onDetachView()
super.onDestroyView()
}
private fun NotificationType.toDestinationFragment(): Fragment? = when (this) {
NotificationType.NEW_CONFERENCE -> ConferenceFragment.newInstance()
NotificationType.NEW_EXAM -> ExamFragment.newInstance()
NotificationType.NEW_GRADE_DETAILS -> GradeFragment.newInstance()
NotificationType.NEW_GRADE_PREDICTED -> GradeFragment.newInstance()
NotificationType.NEW_GRADE_FINAL -> GradeFragment.newInstance()
NotificationType.NEW_HOMEWORK -> HomeworkFragment.newInstance()
NotificationType.NEW_LUCKY_NUMBER -> LuckyNumberFragment.newInstance()
NotificationType.NEW_MESSAGE -> MessageFragment.newInstance()
NotificationType.NEW_NOTE -> NoteFragment.newInstance()
NotificationType.NEW_ANNOUNCEMENT -> SchoolAnnouncementFragment.newInstance()
NotificationType.PUSH -> null
NotificationType.CHANGE_TIMETABLE -> TimetableFragment.newInstance()
NotificationType.NEW_ATTENDANCE -> AttendanceFragment.newInstance()
}
}

View File

@ -48,7 +48,7 @@ class NotificationsCenterPresenter @Inject constructor(
emitAll(notificationRepository.getNotifications(studentId))
}
.map { notificationList -> notificationList.sortedByDescending { it.date } }
.catch { Timber.i("Loading notifications result: An exception occurred") }
.catch { Timber.i("Loading notifications result: An exception occurred: `$it`") }
.onEach {
Timber.i("Loading notifications result: Success")