Add lesson time left display (#550)

This commit is contained in:
Dominik Korsa 2020-05-20 16:06:24 +02:00 committed by GitHub
parent 29226dd93e
commit b95b529015
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 309 additions and 33 deletions

View File

@ -75,6 +75,9 @@ class PreferencesRepository @Inject constructor(
val showWholeClassPlan: String val showWholeClassPlan: String
get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class) get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class)
val showTimetableTimers: Boolean
get() = getBoolean(R.string.pref_key_timetable_show_timers, R.bool.pref_default_timetable_show_timers)
private fun getString(id: Int, default: Int) = getString(context.getString(id), default) private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default) private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default)

View File

@ -179,6 +179,8 @@ class LoginRecoverFragment :
loadDataWithBaseURL(url, html, "text/html", "UTF-8", null) loadDataWithBaseURL(url, html, "text/html", "UTF-8", null)
addJavascriptInterface(object { addJavascriptInterface(object {
@Suppress("UNUSED")
@JavascriptInterface @JavascriptInterface
fun captchaCallback(reCaptchaResponse: String) { fun captchaCallback(reCaptchaResponse: String) {
activity?.runOnUiThread { activity?.runOnUiThread {

View File

@ -2,6 +2,8 @@ package io.github.wulkanowy.ui.modules.timetable
import android.graphics.Paint import android.graphics.Paint
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
@ -10,8 +12,16 @@ import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.ItemTimetableBinding import io.github.wulkanowy.databinding.ItemTimetableBinding
import io.github.wulkanowy.databinding.ItemTimetableSmallBinding import io.github.wulkanowy.databinding.ItemTimetableSmallBinding
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.isJustFinished
import io.github.wulkanowy.utils.isShowTimeUntil
import io.github.wulkanowy.utils.left
import io.github.wulkanowy.utils.toFormattedString import io.github.wulkanowy.utils.toFormattedString
import io.github.wulkanowy.utils.until
import org.threeten.bp.LocalDateTime
import timber.log.Timber
import java.util.Timer
import javax.inject.Inject import javax.inject.Inject
import kotlin.concurrent.timer
class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.ViewHolder>() { class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
@ -20,12 +30,28 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
ITEM_SMALL(2) ITEM_SMALL(2)
} }
var items = emptyList<Timetable>() var items = mutableListOf<Timetable>()
set(value) {
field = value
resetTimers()
}
var onClickListener: (Timetable) -> Unit = {} var onClickListener: (Timetable) -> Unit = {}
var showWholeClassPlan: String = "no" var showWholeClassPlan: String = "no"
var showTimers: Boolean = false
private val timers = mutableMapOf<Int, Timer>()
private fun resetTimers() {
Timber.d("Timetable timers reset")
with(timers) {
forEach { (_, timer) -> timer.cancel() }
clear()
}
}
override fun getItemCount() = items.size override fun getItemCount() = items.size
override fun getItemViewType(position: Int) = when { override fun getItemViewType(position: Int) = when {
@ -43,11 +69,16 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
} }
} }
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
resetTimers()
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val lesson = items[position] val lesson = items[position]
when (holder) { when (holder) {
is ItemViewHolder -> bindNormalView(holder.binding, lesson) is ItemViewHolder -> bindNormalView(holder.binding, lesson, position)
is SmallItemViewHolder -> bindSmallView(holder.binding, lesson) is SmallItemViewHolder -> bindSmallView(holder.binding, lesson)
} }
} }
@ -68,7 +99,7 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
} }
} }
private fun bindNormalView(binding: ItemTimetableBinding, lesson: Timetable) { private fun bindNormalView(binding: ItemTimetableBinding, lesson: Timetable, position: Int) {
with(binding) { with(binding) {
timetableItemNumber.text = lesson.number.toString() timetableItemNumber.text = lesson.number.toString()
timetableItemSubject.text = lesson.subject timetableItemSubject.text = lesson.subject
@ -81,10 +112,74 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
bindNormalDescription(binding, lesson) bindNormalDescription(binding, lesson)
bindNormalColors(binding, lesson) bindNormalColors(binding, lesson)
if (lesson.isStudentPlan && showTimers) timers[position] = timer(period = 1000) {
root.post { updateTimeLeft(binding, lesson, position) }
} else {
// reset item on set changed
timetableItemTimeUntil.visibility = GONE
timetableItemTimeLeft.visibility = GONE
}
root.setOnClickListener { onClickListener(lesson) } root.setOnClickListener { onClickListener(lesson) }
} }
} }
private fun getPreviousLesson(position: Int): LocalDateTime? {
return items.filter { it.isStudentPlan }.getOrNull(position - 1 - items.filterIndexed { i, item -> i < position && !item.isStudentPlan }.size)?.let {
if (!it.canceled && it.isStudentPlan) it.end
else null
}
}
private fun updateTimeLeft(binding: ItemTimetableBinding, lesson: Timetable, position: Int) {
with(binding) {
when {
// before lesson
lesson.isShowTimeUntil(getPreviousLesson(position)) -> {
Timber.d("Show time until lesson: $position")
timetableItemTimeLeft.visibility = GONE
with(timetableItemTimeUntil) {
visibility = VISIBLE
text = context.getString(R.string.timetable_time_until,
if (lesson.until.seconds <= 60) {
context.getString(R.string.timetable_seconds, lesson.until.seconds.toString(10))
} else {
context.getString(R.string.timetable_minutes, lesson.until.toMinutes().toString(10))
}
)
}
}
// after lesson start
lesson.left != null -> {
Timber.d("Show time left lesson: $position")
timetableItemTimeUntil.visibility = GONE
with(timetableItemTimeLeft) {
visibility = VISIBLE
text = context.getString(
R.string.timetable_time_left,
if (lesson.left!!.seconds < 60) {
context.getString(R.string.timetable_seconds, lesson.left?.seconds?.toString(10))
} else {
context.getString(R.string.timetable_minutes, lesson.left?.toMinutes()?.toString(10))
}
)
}
}
// right after lesson finish
lesson.isJustFinished -> {
Timber.d("Show just finished lesson: $position")
timetableItemTimeUntil.visibility = GONE
timetableItemTimeLeft.visibility = VISIBLE
timetableItemTimeLeft.text = root.context.getString(R.string.timetable_finished)
}
else -> {
timetableItemTimeUntil.visibility = GONE
timetableItemTimeLeft.visibility = GONE
}
}
}
}
private fun bindSubjectStyle(subjectView: TextView, lesson: Timetable) { private fun bindSubjectStyle(subjectView: TextView, lesson: Timetable) {
subjectView.paintFlags = if (lesson.canceled) subjectView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG subjectView.paintFlags = if (lesson.canceled) subjectView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
else subjectView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv() else subjectView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
@ -93,20 +188,20 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
private fun bindSmallDescription(binding: ItemTimetableSmallBinding, lesson: Timetable) { private fun bindSmallDescription(binding: ItemTimetableSmallBinding, lesson: Timetable) {
with(binding) { with(binding) {
if (lesson.info.isNotBlank() && !lesson.changes) { if (lesson.info.isNotBlank() && !lesson.changes) {
timetableSmallItemDescription.visibility = android.view.View.VISIBLE timetableSmallItemDescription.visibility = VISIBLE
timetableSmallItemDescription.text = lesson.info timetableSmallItemDescription.text = lesson.info
timetableSmallItemRoom.visibility = android.view.View.GONE timetableSmallItemRoom.visibility = GONE
timetableSmallItemTeacher.visibility = android.view.View.GONE timetableSmallItemTeacher.visibility = GONE
timetableSmallItemDescription.setTextColor(root.context.getThemeAttrColor( timetableSmallItemDescription.setTextColor(root.context.getThemeAttrColor(
if (lesson.canceled) R.attr.colorPrimary if (lesson.canceled) R.attr.colorPrimary
else R.attr.colorTimetableChange else R.attr.colorTimetableChange
)) ))
} else { } else {
timetableSmallItemDescription.visibility = android.view.View.GONE timetableSmallItemDescription.visibility = GONE
timetableSmallItemRoom.visibility = android.view.View.VISIBLE timetableSmallItemRoom.visibility = VISIBLE
timetableSmallItemTeacher.visibility = android.view.View.VISIBLE timetableSmallItemTeacher.visibility = VISIBLE
} }
} }
} }
@ -114,20 +209,20 @@ class TimetableAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView
private fun bindNormalDescription(binding: ItemTimetableBinding, lesson: Timetable) { private fun bindNormalDescription(binding: ItemTimetableBinding, lesson: Timetable) {
with(binding) { with(binding) {
if (lesson.info.isNotBlank() && !lesson.changes) { if (lesson.info.isNotBlank() && !lesson.changes) {
timetableItemDescription.visibility = android.view.View.VISIBLE timetableItemDescription.visibility = VISIBLE
timetableItemDescription.text = lesson.info timetableItemDescription.text = lesson.info
timetableItemRoom.visibility = android.view.View.GONE timetableItemRoom.visibility = GONE
timetableItemTeacher.visibility = android.view.View.GONE timetableItemTeacher.visibility = GONE
timetableItemDescription.setTextColor(root.context.getThemeAttrColor( timetableItemDescription.setTextColor(root.context.getThemeAttrColor(
if (lesson.canceled) R.attr.colorPrimary if (lesson.canceled) R.attr.colorPrimary
else R.attr.colorTimetableChange else R.attr.colorTimetableChange
)) ))
} else { } else {
timetableItemDescription.visibility = android.view.View.GONE timetableItemDescription.visibility = GONE
timetableItemRoom.visibility = android.view.View.VISIBLE timetableItemRoom.visibility = VISIBLE
timetableItemTeacher.visibility = android.view.View.VISIBLE timetableItemTeacher.visibility = VISIBLE
} }
} }
} }

View File

@ -86,9 +86,10 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
else false else false
} }
override fun updateData(data: List<Timetable>, showWholeClassPlanType: String) { override fun updateData(data: List<Timetable>, showWholeClassPlanType: String, showTimetableTimers: Boolean) {
with(timetableAdapter) { with(timetableAdapter) {
items = data items = data.toMutableList()
showTimers = showTimetableTimers
showWholeClassPlan = showWholeClassPlanType showWholeClassPlan = showWholeClassPlanType
notifyDataSetChanged() notifyDataSetChanged()
} }
@ -96,7 +97,7 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
override fun clearData() { override fun clearData() {
with(timetableAdapter) { with(timetableAdapter) {
items = emptyList() items = mutableListOf()
notifyDataSetChanged() notifyDataSetChanged()
} }
} }

View File

@ -149,7 +149,7 @@ class TimetablePresenter @Inject constructor(
.subscribe({ .subscribe({
Timber.i("Loading timetable result: Success") Timber.i("Loading timetable result: Success")
view?.apply { view?.apply {
updateData(it, prefRepository.showWholeClassPlan) updateData(it, prefRepository.showWholeClassPlan, prefRepository.showTimetableTimers)
showEmpty(it.isEmpty()) showEmpty(it.isEmpty())
showErrorView(false) showErrorView(false)
showContent(it.isNotEmpty()) showContent(it.isNotEmpty())

View File

@ -12,7 +12,7 @@ interface TimetableView : BaseView {
fun initView() fun initView()
fun updateData(data: List<Timetable>, showWholeClassPlanType: String) fun updateData(data: List<Timetable>, showWholeClassPlanType: String, showTimetableTimers: Boolean)
fun updateNavigationDay(date: String) fun updateNavigationDay(date: String)

View File

@ -0,0 +1,29 @@
package io.github.wulkanowy.utils
import io.github.wulkanowy.data.db.entities.Timetable
import org.threeten.bp.Duration
import org.threeten.bp.Duration.between
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalDateTime.now
fun Timetable.isShowTimeUntil(previousLessonEnd: LocalDateTime?) = when {
!isStudentPlan -> false
canceled -> false
now().isAfter(start) -> false
previousLessonEnd != null && now().isBefore(previousLessonEnd) -> false
else -> between(now(), start) <= Duration.ofMinutes(60)
}
inline val Timetable.left: Duration?
get() = when {
canceled -> null
!isStudentPlan -> null
end.isAfter(now()) && start.isBefore(now()) -> between(now(), end)
else -> null
}
inline val Timetable.until: Duration
get() = between(now(), start)
inline val Timetable.isJustFinished: Boolean
get() = end.isBefore(now()) && end.plusSeconds(15).isAfter(now()) && !canceled

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?colorPrimary"/>
<corners android:radius="3dp"/>
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>

View File

@ -29,12 +29,12 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="10dp" android:layout_marginStart="10dp"
android:layout_marginEnd="40dp" android:layout_marginEnd="16dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="15sp" android:textSize="15sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toStartOf="@id/timetableItemTimeBarrier"
app:layout_constraintStart_toEndOf="@+id/timetableItemTimeStart" app:layout_constraintStart_toEndOf="@+id/timetableItemTimeStart"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" /> tools:text="@tools:sample/lorem" />
@ -106,4 +106,56 @@
tools:text="Lekcja odwołana: uczniowie zwolnieni do domu" tools:text="Lekcja odwołana: uczniowie zwolnieni do domu"
tools:visibility="visible" /> tools:visibility="visible" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/timetableItemTimeBarrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="start"
app:constraint_referenced_ids="timetableItemTimeUntil,timetableItemTimeLeft" />
<TextView
android:id="@+id/timetableItemTimeUntil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/timetableItemSubject"
android:layout_alignBottom="@id/timetableItemSubject"
android:layout_alignParentEnd="true"
android:layout_marginStart="4dp"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="?colorPrimary"
android:textSize="13sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="za 15 min"
tools:visibility="gone" />
<TextView
android:id="@+id/timetableItemTimeLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/timetableItemSubject"
android:layout_alignBottom="@id/timetableItemSubject"
android:layout_alignParentEnd="true"
android:layout_marginStart="4dp"
android:background="@drawable/background_timetable_time_left"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:includeFontPadding="false"
android:paddingLeft="7dp"
android:paddingRight="7dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:textColor="?colorOnPrimary"
android:textSize="13sp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="jeszcze 15 min"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -121,6 +121,11 @@
<string name="timetable_time">Godziny</string> <string name="timetable_time">Godziny</string>
<string name="timetable_changes">Zmiany</string> <string name="timetable_changes">Zmiany</string>
<string name="timetable_no_items">Brak lekcji w tym dniu</string> <string name="timetable_no_items">Brak lekcji w tym dniu</string>
<string name="timetable_minutes">%s min</string>
<string name="timetable_seconds">%s sek</string>
<string name="timetable_time_left">jeszcze %1$s</string>
<string name="timetable_time_until">za %1$s</string>
<string name="timetable_finished">Zakończona</string>
<string name="timetable_now">Teraz: %s</string> <string name="timetable_now">Teraz: %s</string>
<string name="timetable_next">Za chwilę: %s</string> <string name="timetable_next">Za chwilę: %s</string>
<string name="timetable_later">Później: %s</string> <string name="timetable_later">Później: %s</string>
@ -317,6 +322,7 @@
<string name="pref_view_app_theme">Motyw aplikacji</string> <string name="pref_view_app_theme">Motyw aplikacji</string>
<string name="pref_view_expand_grade">Rozwiń oceny</string> <string name="pref_view_expand_grade">Rozwiń oceny</string>
<string name="pref_view_grade_statistics_list">Pokazuj listę wykresów w ocenach klasy</string> <string name="pref_view_grade_statistics_list">Pokazuj listę wykresów w ocenach klasy</string>
<string name="pref_view_timetable_show_timers">Oznaczaj bieżącą lekcję na planie</string>
<string name="pref_view_timetable_show_whole_class">Pokazuj lekcje całej klasy</string> <string name="pref_view_timetable_show_whole_class">Pokazuj lekcje całej klasy</string>
<string name="pref_view_grade_color_scheme">Schemat kolorów ocen</string> <string name="pref_view_grade_color_scheme">Schemat kolorów ocen</string>
<string name="pref_view_app_language">Język aplikacji</string> <string name="pref_view_app_language">Język aplikacji</string>

View File

@ -19,4 +19,5 @@
<string name="pref_default_grade_modifier_minus">0.33</string> <string name="pref_default_grade_modifier_minus">0.33</string>
<bool name="pref_default_fill_message_content">true</bool> <bool name="pref_default_fill_message_content">true</bool>
<string name="pref_default_timetable_show_whole_class">no</string> <string name="pref_default_timetable_show_whole_class">no</string>
<bool name="pref_default_timetable_show_timers">false</bool>
</resources> </resources>

View File

@ -20,4 +20,5 @@
<string name="pref_key_grade_modifier_minus">grade_modifier_minus</string> <string name="pref_key_grade_modifier_minus">grade_modifier_minus</string>
<string name="pref_key_fill_message_content">fill_message_content</string> <string name="pref_key_fill_message_content">fill_message_content</string>
<string name="pref_key_timetable_show_whole_class">show_whole_class_plan</string> <string name="pref_key_timetable_show_whole_class">show_whole_class_plan</string>
<string name="pref_key_timetable_show_timers">timetable_show_timers</string>
</resources> </resources>

View File

@ -130,6 +130,11 @@
<string name="timetable_time">Hours</string> <string name="timetable_time">Hours</string>
<string name="timetable_changes">Changes</string> <string name="timetable_changes">Changes</string>
<string name="timetable_no_items">No lessons this day</string> <string name="timetable_no_items">No lessons this day</string>
<string name="timetable_minutes">%s min</string>
<string name="timetable_seconds">%s sec</string>
<string name="timetable_time_left">%1$s left</string>
<string name="timetable_time_until">in %1$s</string>
<string name="timetable_finished">Finished</string>
<string name="timetable_now">Now: %s</string> <string name="timetable_now">Now: %s</string>
<string name="timetable_next">Next: %s</string> <string name="timetable_next">Next: %s</string>
<string name="timetable_later">Later: %s</string> <string name="timetable_later">Later: %s</string>
@ -352,6 +357,7 @@
<string name="pref_view_present">Show presence in attendance</string> <string name="pref_view_present">Show presence in attendance</string>
<string name="pref_view_app_theme">Application theme</string> <string name="pref_view_app_theme">Application theme</string>
<string name="pref_view_expand_grade">Expand grades</string> <string name="pref_view_expand_grade">Expand grades</string>
<string name="pref_view_timetable_show_timers">Mark current lesson in timetable</string>
<string name="pref_view_grade_statistics_list">Show chart list in class grades</string> <string name="pref_view_grade_statistics_list">Show chart list in class grades</string>
<string name="pref_view_timetable_show_whole_class">Show whole class lessons</string> <string name="pref_view_timetable_show_whole_class">Show whole class lessons</string>
<string name="pref_view_grade_color_scheme">Grades color scheme</string> <string name="pref_view_grade_color_scheme">Grades color scheme</string>

View File

@ -29,6 +29,11 @@
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:key="@string/pref_key_expand_grade" app:key="@string/pref_key_expand_grade"
app:title="@string/pref_view_expand_grade" /> app:title="@string/pref_view_expand_grade" />
<SwitchPreferenceCompat
app:defaultValue="@bool/pref_default_timetable_show_timers"
app:iconSpaceReserved="false"
app:title="@string/pref_view_timetable_show_timers"
app:key="@string/pref_key_timetable_show_timers" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
app:defaultValue="@bool/pref_default_grade_statistics_list" app:defaultValue="@bool/pref_default_grade_statistics_list"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"

View File

@ -1,9 +1,11 @@
package io.github.wulkanowy.data.repositories package io.github.wulkanowy
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalDateTime.now import org.threeten.bp.LocalDateTime.now
fun createSemesterEntity(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalDate, semesterName: Int = 1): Semester { fun createSemesterEntity(diaryId: Int, semesterId: Int, start: LocalDate, end: LocalDate, semesterName: Int = 1): Semester {
@ -45,3 +47,28 @@ fun getStudentEntity(mode: Sdk.Mode = Sdk.Mode.API): Student {
userLoginId = 0 userLoginId = 0
) )
} }
fun getTimetableEntity(
isStudentPlan: Boolean = false,
canceled: Boolean = false,
start: LocalDateTime = now(),
end: LocalDateTime = now()
) = Timetable(
studentId = 0,
subject = "",
number = 0,
diaryId = 0,
canceled = canceled,
changes = false,
date = LocalDate.now(),
end = end,
group = "",
info = "",
isStudentPlan = isStudentPlan,
room = "",
roomOld = "",
start = start,
subjectOld = "",
teacher = "",
teacherOld = ""
)

View File

@ -1,8 +1,7 @@
package io.github.wulkanowy.data.repositories.attendance package io.github.wulkanowy.data.repositories.attendance
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.data.repositories.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Attendance import io.github.wulkanowy.sdk.pojo.Attendance
import io.github.wulkanowy.utils.init import io.github.wulkanowy.utils.init

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.data.repositories.completedlessons package io.github.wulkanowy.data.repositories.completedlessons
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.CompletedLesson import io.github.wulkanowy.sdk.pojo.CompletedLesson
import io.github.wulkanowy.utils.init import io.github.wulkanowy.utils.init

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.data.repositories.exam package io.github.wulkanowy.data.repositories.exam
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Exam import io.github.wulkanowy.sdk.pojo.Exam
import io.github.wulkanowy.utils.init import io.github.wulkanowy.utils.init

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.data.repositories.gradestatistics package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.GradePointsStatistics import io.github.wulkanowy.sdk.pojo.GradePointsStatistics
import io.github.wulkanowy.sdk.pojo.GradeStatistics import io.github.wulkanowy.sdk.pojo.GradeStatistics

View File

@ -1,6 +1,6 @@
package io.github.wulkanowy.data.repositories.luckynumber package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init import io.github.wulkanowy.utils.init
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations

View File

@ -4,7 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.Single import io.reactivex.Single
import org.junit.Before import org.junit.Before

View File

@ -4,7 +4,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
import io.github.wulkanowy.data.repositories.createSemesterEntity import io.github.wulkanowy.createSemesterEntity
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.Single import io.reactivex.Single
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals

View File

@ -1,7 +1,7 @@
package io.github.wulkanowy.data.repositories.timetable package io.github.wulkanowy.data.repositories.timetable
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.getStudentEntity import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Timetable import io.github.wulkanowy.sdk.pojo.Timetable
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations

View File

@ -3,9 +3,9 @@ package io.github.wulkanowy.ui.modules.grade
import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.createSemesterEntity
import io.github.wulkanowy.data.repositories.grade.GradeRepository import io.github.wulkanowy.data.repositories.grade.GradeRepository
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.createSemesterEntity
import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.sdk.Sdk import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single

View File

@ -0,0 +1,43 @@
package io.github.wulkanowy.utils
import io.github.wulkanowy.getTimetableEntity
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue
import org.junit.Test
import org.threeten.bp.LocalDateTime.now
class TimetableExtensionTest {
@Test
fun isShowTimeUntil() {
assertFalse(getTimetableEntity().isShowTimeUntil(null))
assertFalse(getTimetableEntity(isStudentPlan = false).isShowTimeUntil(null))
assertFalse(getTimetableEntity(isStudentPlan = true, canceled = true).isShowTimeUntil(null))
assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().minusSeconds(1)).isShowTimeUntil(null))
assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(5)).isShowTimeUntil(now().plusMinutes(5)))
assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(61)).isShowTimeUntil(now().minusMinutes(5)))
assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(60)).isShowTimeUntil(now().minusMinutes(5)))
assertTrue(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().plusMinutes(60)).isShowTimeUntil(null))
assertFalse(getTimetableEntity(isStudentPlan = true, canceled = false, start = now().minusSeconds(1)).isShowTimeUntil(null))
}
@Test
fun getLeft() {
assertEquals(null, getTimetableEntity(canceled = true).left)
assertEquals(null, getTimetableEntity(start = now().plusMinutes(5), end = now().plusMinutes(50)).left)
assertEquals(null, getTimetableEntity(start = now().minusMinutes(1), end = now().plusMinutes(44), isStudentPlan = false).left)
assertNotEquals(null, getTimetableEntity(start = now().minusMinutes(1), end = now().plusMinutes(44), isStudentPlan = true).left)
}
@Test
fun isJustFinished() {
assertFalse(getTimetableEntity(end = now().minusSeconds(16)).isJustFinished)
assertTrue(getTimetableEntity(end = now().minusSeconds(14)).isJustFinished)
assertTrue(getTimetableEntity(end = now().minusSeconds(1)).isJustFinished)
assertFalse(getTimetableEntity(end = now().plusSeconds(1)).isJustFinished)
}
}