[Timetable] Implement lazy day loading. Introduce TimetableManager class.

This commit is contained in:
Kuba Szczodrzyński 2020-03-10 19:27:18 +01:00
parent 06011bf4ae
commit acd5e9b998
10 changed files with 95 additions and 58 deletions

View File

@ -47,6 +47,7 @@ import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
import pl.szczodrzynski.edziennik.utils.* import pl.szczodrzynski.edziennik.utils.*
import pl.szczodrzynski.edziennik.utils.managers.GradesManager import pl.szczodrzynski.edziennik.utils.managers.GradesManager
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
import pl.szczodrzynski.edziennik.utils.managers.TimetableManager
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -67,6 +68,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
val notificationChannelsManager by lazy { NotificationChannelsManager(this) } val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
val userActionManager by lazy { UserActionManager(this) } val userActionManager by lazy { UserActionManager(this) }
val gradesManager by lazy { GradesManager(this) } val gradesManager by lazy { GradesManager(this) }
val timetableManager by lazy { TimetableManager(this) }
val db val db
get() = App.db get() = App.db

View File

@ -5,10 +5,9 @@
package pl.szczodrzynski.edziennik.data.db.dao package pl.szczodrzynski.edziennik.data.db.dao
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.room.Dao import androidx.room.*
import androidx.room.Insert import androidx.sqlite.db.SimpleSQLiteQuery
import androidx.room.OnConflictStrategy import androidx.sqlite.db.SupportSQLiteQuery
import androidx.room.Query
import pl.szczodrzynski.edziennik.data.db.entity.Lesson import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.LessonFull import pl.szczodrzynski.edziennik.data.db.full.LessonFull
@ -53,6 +52,9 @@ interface TimetableDao {
@Query("DELETE FROM timetable WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))") @Query("DELETE FROM timetable WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))")
fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date) fun clearBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
@RawQuery(observedEntities = [Lesson::class])
fun getRaw(query: SupportSQLiteQuery): LiveData<List<LessonFull>>
@Query(""" @Query("""
$QUERY $QUERY
WHERE timetable.profileId = :profileId AND type != -1 AND type != 0 WHERE timetable.profileId = :profileId AND type != -1 AND type != 0
@ -67,12 +69,11 @@ interface TimetableDao {
""") """)
fun getChangesForDateNow(profileId: Int, date: Date): List<LessonFull> fun getChangesForDateNow(profileId: Int, date: Date): List<LessonFull>
@Query(""" fun getForDate(profileId: Int, date: Date) = getRaw(SimpleSQLiteQuery("""
$QUERY $QUERY
WHERE timetable.profileId = :profileId AND ((type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)) WHERE timetable.profileId = $profileId AND ((type != 3 AND date = "${date.stringY_m_d}") OR ((type = 3 OR type = 1) AND oldDate = "${date.stringY_m_d}"))
ORDER BY id, type ORDER BY id, type
""") """))
fun getForDate(profileId: Int, date: Date): LiveData<List<LessonFull>>
@Query(""" @Query("""
$QUERY $QUERY

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.db.entity package pl.szczodrzynski.edziennik.data.db.entity
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index import androidx.room.Index
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
@ -66,6 +67,9 @@ open class Lesson(val profileId: Int, var id: Long) {
fun buildId(): Long = (displayDate?.combineWith(displayStartTime) ?: 0L) / 6L * 10L + (hashCode() and 0xFFFF) fun buildId(): Long = (displayDate?.combineWith(displayStartTime) ?: 0L) / 6L * 10L + (hashCode() and 0xFFFF)
@Ignore
var showAsUnseen = false
override fun toString(): String { override fun toString(): String {
return "Lesson(profileId=$profileId, " + return "Lesson(profileId=$profileId, " +
"id=$id, " + "id=$id, " +

View File

@ -25,7 +25,6 @@ import pl.szczodrzynski.edziennik.ui.dialogs.event.EventDetailsDialog
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListAdapter import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListAdapter
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableUtils
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
@ -50,7 +49,7 @@ class LessonDetailsDialog(
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
private lateinit var adapter: EventListAdapter private lateinit var adapter: EventListAdapter
private val utils by lazy { TimetableUtils() } private val manager by lazy { app.timetableManager }
init { run { init { run {
if (activity.isFinishing) if (activity.isFinishing)
@ -91,7 +90,7 @@ class LessonDetailsDialog(
val lessonTime = lesson.displayStartTime ?: return val lessonTime = lesson.displayStartTime ?: return
b.lessonDate.text = Week.getFullDayName(lessonDate.weekDay) + ", " + lessonDate.formattedString b.lessonDate.text = Week.getFullDayName(lessonDate.weekDay) + ", " + lessonDate.formattedString
b.annotationVisible = utils.getAnnotation(activity, lesson, b.annotation) b.annotationVisible = manager.getAnnotation(activity, lesson, b.annotation)
if (lesson.type >= Lesson.TYPE_SHIFTED_SOURCE) { if (lesson.type >= Lesson.TYPE_SHIFTED_SOURCE) {
b.shiftedLayout.visibility = View.VISIBLE b.shiftedLayout.visibility = View.VISIBLE

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-2-22.
*/
package pl.szczodrzynski.edziennik.ui.modules.base
import androidx.fragment.app.Fragment
abstract class PagerFragment : Fragment() {
private var isPageCreated = false
/**
* Called when the page is first shown, or if previous
* [onPageCreated] returned false
*
* @return true if the view is set up
* @return false if the setup failed. The method may be then called
* again, when page becomes visible.
*/
abstract fun onPageCreated(): Boolean
override fun onResume() {
if (!isPageCreated) {
isPageCreated = onPageCreated()
}
super.onResume()
}
}

View File

@ -5,15 +5,15 @@
package pl.szczodrzynski.edziennik.ui.modules.timetable package pl.szczodrzynski.edziennik.ui.modules.timetable
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import androidx.asynclayoutinflater.view.AsyncLayoutInflater import androidx.asynclayoutinflater.view.AsyncLayoutInflater
import androidx.core.view.setPadding import androidx.core.view.setPadding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
import com.linkedin.android.tachyon.DayView import com.linkedin.android.tachyon.DayView
import com.linkedin.android.tachyon.DayViewConfig import com.linkedin.android.tachyon.DayViewConfig
@ -27,6 +27,7 @@ import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.databinding.TimetableLessonBinding import pl.szczodrzynski.edziennik.databinding.TimetableLessonBinding
import pl.szczodrzynski.edziennik.databinding.TimetableNoTimetableBinding import pl.szczodrzynski.edziennik.databinding.TimetableNoTimetableBinding
import pl.szczodrzynski.edziennik.ui.dialogs.timetable.LessonDetailsDialog import pl.szczodrzynski.edziennik.ui.dialogs.timetable.LessonDetailsDialog
import pl.szczodrzynski.edziennik.ui.modules.base.PagerFragment
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment.Companion.DEFAULT_END_HOUR import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment.Companion.DEFAULT_END_HOUR
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment.Companion.DEFAULT_START_HOUR import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment.Companion.DEFAULT_START_HOUR
import pl.szczodrzynski.edziennik.utils.ListenerScrollView import pl.szczodrzynski.edziennik.utils.ListenerScrollView
@ -35,7 +36,7 @@ import java.util.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.math.min import kotlin.math.min
class TimetableDayFragment : Fragment(), CoroutineScope { class TimetableDayFragment : PagerFragment(), CoroutineScope {
companion object { companion object {
private const val TAG = "TimetableDayFragment" private const val TAG = "TimetableDayFragment"
} }
@ -44,7 +45,7 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
private lateinit var activity: MainActivity private lateinit var activity: MainActivity
private lateinit var inflater: AsyncLayoutInflater private lateinit var inflater: AsyncLayoutInflater
private lateinit var job: Job private val job: Job = Job()
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
@ -53,7 +54,7 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
private var endHour = DEFAULT_END_HOUR private var endHour = DEFAULT_END_HOUR
private var firstEventMinute = 24 * 60 private var firstEventMinute = 24 * 60
private val utils by lazy { TimetableUtils() } private val manager by lazy { app.timetableManager }
// find SwipeRefreshLayout in the hierarchy // find SwipeRefreshLayout in the hierarchy
private val refreshLayout by lazy { view?.findParentById(R.id.refreshLayout) } private val refreshLayout by lazy { view?.findParentById(R.id.refreshLayout) }
@ -88,25 +89,23 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null activity = (getActivity() as MainActivity?) ?: return null
if (context == null) context ?: return null
return null
app = activity.application as App app = activity.application as App
job = Job()
this.inflater = AsyncLayoutInflater(context!!) this.inflater = AsyncLayoutInflater(context!!)
date = arguments?.getInt("date")?.let { Date.fromValue(it) } ?: Date.getToday() date = arguments?.getInt("date")?.let { Date.fromValue(it) } ?: Date.getToday()
startHour = arguments?.getInt("startHour") ?: DEFAULT_START_HOUR startHour = arguments?.getInt("startHour") ?: DEFAULT_START_HOUR
endHour = arguments?.getInt("endHour") ?: DEFAULT_END_HOUR endHour = arguments?.getInt("endHour") ?: DEFAULT_END_HOUR
return FrameLayout(activity).apply { return FrameLayout(activity).apply {
layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
addView(ProgressBar(activity).apply {
layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER)
})
} }
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onPageCreated(): Boolean {
// TODO check if app, activity, b can be null if (!isAdded)
if (app.profile == null || !isAdded) return false
return
Log.d(TAG, "onViewCreated, date=$date")
// observe lesson database // observe lesson database
app.db.timetableDao().getForDate(App.profileId, date).observe(this, Observer { lessons -> app.db.timetableDao().getForDate(App.profileId, date).observe(this, Observer { lessons ->
@ -117,6 +116,8 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
processLessonList(lessons, events) processLessonList(lessons, events)
} }
}) })
return true
} }
private fun processLessonList(lessons: List<LessonFull>, events: List<EventFull>) { private fun processLessonList(lessons: List<LessonFull>, events: List<EventFull>) {
@ -174,6 +175,8 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
} }
dayView.setHourLabelViews(hourLabelViews) dayView.setHourLabelViews(hourLabelViews)
lessons.forEach { it.showAsUnseen = !it.seen }
buildLessonViews(lessons.filter { it.type != Lesson.TYPE_NO_LESSONS }, events) buildLessonViews(lessons.filter { it.type != Lesson.TYPE_NO_LESSONS }, events)
} }
@ -209,7 +212,6 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
eventView.tag = lesson eventView.tag = lesson
eventView.setOnClickListener { eventView.setOnClickListener {
Log.d(TAG, "Clicked ${it.tag}")
if (isAdded && it.tag is LessonFull) if (isAdded && it.tag is LessonFull)
LessonDetailsDialog(activity, it.tag as LessonFull) LessonDetailsDialog(activity, it.tag as LessonFull)
} }
@ -275,10 +277,13 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
lb.detailsFirst.text = listOfNotEmpty(timeRange, classroomInfo).concat(bullet) lb.detailsFirst.text = listOfNotEmpty(timeRange, classroomInfo).concat(bullet)
lb.detailsSecond.text = listOfNotEmpty(teacherInfo, teamInfo).concat(bullet) lb.detailsSecond.text = listOfNotEmpty(teacherInfo, teamInfo).concat(bullet)
lb.unread = lesson.type != Lesson.TYPE_NORMAL && !lesson.seen lb.unread = lesson.type != Lesson.TYPE_NORMAL && lesson.showAsUnseen
if (!lesson.seen) {
manager.markAsSeen(lesson)
}
//lb.subjectName.typeface = Typeface.create("sans-serif-light", Typeface.BOLD) //lb.subjectName.typeface = Typeface.create("sans-serif-light", Typeface.BOLD)
lb.annotationVisible = utils.getAnnotation(activity, lesson, lb.annotation) lb.annotationVisible = manager.getAnnotation(activity, lesson, lb.annotation)
// The day view needs the event time ranges in the start minute/end minute format, // The day view needs the event time ranges in the start minute/end minute format,
// so calculate those here // so calculate those here

View File

@ -15,7 +15,6 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.datepicker.MaterialDatePicker
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
@ -26,12 +25,9 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Metadata import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
import pl.szczodrzynski.edziennik.observeOnce
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.ui.dialogs.timetable.GenerateBlockTimetableDialog import pl.szczodrzynski.edziennik.ui.dialogs.timetable.GenerateBlockTimetableDialog
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
@ -50,7 +46,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
private lateinit var activity: MainActivity private lateinit var activity: MainActivity
private lateinit var b: FragmentTimetableV2Binding private lateinit var b: FragmentTimetableV2Binding
private lateinit var job: Job private val job: Job = Job()
override val coroutineContext: CoroutineContext override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main get() = job + Dispatchers.Main
@ -61,11 +57,6 @@ class TimetableFragment : Fragment(), CoroutineScope {
activity = (getActivity() as MainActivity?) ?: return null activity = (getActivity() as MainActivity?) ?: return null
context ?: return null context ?: return null
app = activity.application as App app = activity.application as App
job = Job()
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = FragmentTimetableV2Binding.inflate(inflater) b = FragmentTimetableV2Binding.inflate(inflater)
// TODO: 2020-01-05 resolve issues with page scrolling (and scrolling up) with viewpager and swipe to refresh // TODO: 2020-01-05 resolve issues with page scrolling (and scrolling up) with viewpager and swipe to refresh
//b.refreshLayout.setParent(activity.swipeRefreshLayout) //b.refreshLayout.setParent(activity.swipeRefreshLayout)
@ -91,8 +82,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { launch { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { launch {
// TODO check if app, activity, b can be null if (!isAdded)
if (app.profile == null || !isAdded)
return@launch return@launch
if (app.profile.getStudentData("timetableNotPublic", false)) { if (app.profile.getStudentData("timetableNotPublic", false)) {
@ -141,7 +131,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
startHour, startHour,
endHour endHour
) )
b.viewPager.offscreenPageLimit = 2 b.viewPager.offscreenPageLimit = 1
b.viewPager.adapter = pagerAdapter b.viewPager.adapter = pagerAdapter
b.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { b.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) { override fun onPageScrollStateChanged(state: Int) {
@ -162,7 +152,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
activity.gainAttentionFAB() activity.gainAttentionFAB()
fabShown = true fabShown = true
} }
markLessonsAsSeen() //markLessonsAsSeen()
} }
}) })
@ -224,7 +214,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
}) })
}} }}
private fun markLessonsAsSeen() = pageSelection?.let { date -> /*private fun markLessonsAsSeen() = pageSelection?.let { date ->
app.db.timetableDao().getForDate(App.profileId, date).observeOnce(this@TimetableFragment, Observer { lessons -> app.db.timetableDao().getForDate(App.profileId, date).observeOnce(this@TimetableFragment, Observer { lessons ->
lessons.forEach { lesson -> lessons.forEach { lesson ->
if (lesson.type != Lesson.TYPE_NORMAL && lesson.type != Lesson.TYPE_NO_LESSONS if (lesson.type != Lesson.TYPE_NORMAL && lesson.type != Lesson.TYPE_NO_LESSONS
@ -233,5 +223,5 @@ class TimetableFragment : Fragment(), CoroutineScope {
} }
} }
}) })
} }*/
} }

View File

@ -33,11 +33,6 @@ class TimetablePagerAdapter(
putInt("endHour", endHour) putInt("endHour", endHour)
} }
} }
/*return TimetableDayFragment().apply {
arguments = Bundle().also {
it.putLong("date", items[position].value.toLong())
}
}*/
} }
override fun getCount(): Int { override fun getCount(): Int {

View File

@ -1,22 +1,35 @@
/* /*
* Copyright (c) Kuba Szczodrzyński 2020-2-16. * Copyright (c) Kuba Szczodrzyński 2020-3-10.
*/ */
package pl.szczodrzynski.edziennik.ui.modules.timetable package pl.szczodrzynski.edziennik.utils.managers
import android.content.Context import android.content.Context
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter import android.graphics.PorterDuffColorFilter
import android.widget.TextView import android.widget.TextView
import pl.szczodrzynski.edziennik.R import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Lesson import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.full.LessonFull import pl.szczodrzynski.edziennik.data.db.full.LessonFull
import pl.szczodrzynski.edziennik.resolveAttr
import pl.szczodrzynski.edziennik.setText
import pl.szczodrzynski.edziennik.setTintColor
import pl.szczodrzynski.navlib.getColorFromAttr import pl.szczodrzynski.navlib.getColorFromAttr
import kotlin.coroutines.CoroutineContext
class TimetableManager(val app: App) : CoroutineScope {
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Default
fun markAsSeen(lesson: LessonFull) {
lesson.seen = true
startCoroutineTimer(500L, 0L) {
app.db.metadataDao().setSeen(lesson.profileId, lesson, true)
}
}
class TimetableUtils {
fun getAnnotation(context: Context, lesson: LessonFull, annotation: TextView): Boolean { fun getAnnotation(context: Context, lesson: LessonFull, annotation: TextView): Boolean {
var annotationVisible = false var annotationVisible = false
when (lesson.type) { when (lesson.type) {

View File

@ -74,8 +74,8 @@
tools:text="pracownia urządzeń techniki komputerowej" /> tools:text="pracownia urządzeń techniki komputerowej" />
<View <View
android:layout_width="8dp" android:layout_width="12dp"
android:layout_height="8dp" android:layout_height="12dp"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"