mirror of
https://github.com/wulkanowy/wulkanowy.git
synced 2025-01-31 23:52:44 +01:00
Add lesson time left display (#550)
This commit is contained in:
parent
29226dd93e
commit
b95b529015
@ -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)
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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())
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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
|
@ -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>
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
@ -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"
|
||||||
|
@ -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 = ""
|
||||||
|
)
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user