mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 12:56:45 -06:00
[UI] Implement home timetable card.
This commit is contained in:
parent
7961a74995
commit
37f3d76fb8
13
app/sampledata/settings/ic_settings.xml
Normal file
13
app/sampledata/settings/ic_settings.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2019-11-25.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,8A4,4 0,0 1,16 12A4,4 0,0 1,12 16A4,4 0,0 1,8 12A4,4 0,0 1,12 8M12,10A2,2 0,0 0,10 12A2,2 0,0 0,12 14A2,2 0,0 0,14 12A2,2 0,0 0,12 10M10,22C9.75,22 9.54,21.82 9.5,21.58L9.13,18.93C8.5,18.68 7.96,18.34 7.44,17.94L4.95,18.95C4.73,19.03 4.46,18.95 4.34,18.73L2.34,15.27C2.21,15.05 2.27,14.78 2.46,14.63L4.57,12.97L4.5,12L4.57,11L2.46,9.37C2.27,9.22 2.21,8.95 2.34,8.73L4.34,5.27C4.46,5.05 4.73,4.96 4.95,5.05L7.44,6.05C7.96,5.66 8.5,5.32 9.13,5.07L9.5,2.42C9.54,2.18 9.75,2 10,2H14C14.25,2 14.46,2.18 14.5,2.42L14.87,5.07C15.5,5.32 16.04,5.66 16.56,6.05L19.05,5.05C19.27,4.96 19.54,5.05 19.66,5.27L21.66,8.73C21.79,8.95 21.73,9.22 21.54,9.37L19.43,11L19.5,12L19.43,13L21.54,14.63C21.73,14.78 21.79,15.05 21.66,15.27L19.66,18.73C19.54,18.95 19.27,19.04 19.05,18.95L16.56,17.95C16.04,18.34 15.5,18.68 14.87,18.93L14.5,21.58C14.46,21.82 14.25,22 14,22H10M11.25,4L10.88,6.61C9.68,6.86 8.62,7.5 7.85,8.39L5.44,7.35L4.69,8.65L6.8,10.2C6.4,11.37 6.4,12.64 6.8,13.8L4.68,15.36L5.43,16.66L7.86,15.62C8.63,16.5 9.68,17.14 10.87,17.38L11.24,20H12.76L13.13,17.39C14.32,17.14 15.37,16.5 16.14,15.62L18.57,16.66L19.32,15.36L17.2,13.81C17.6,12.64 17.6,11.37 17.2,10.2L19.31,8.65L18.56,7.35L16.15,8.39C15.38,7.5 14.32,6.86 13.12,6.62L12.75,4H11.25Z"/>
|
||||||
|
</vector>
|
@ -36,7 +36,6 @@ import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
|||||||
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
|
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team
|
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import pl.szczodrzynski.navlib.R
|
|
||||||
import pl.szczodrzynski.navlib.getColorFromRes
|
import pl.szczodrzynski.navlib.getColorFromRes
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -379,13 +378,13 @@ fun CharSequence?.asItalicSpannable(): Spannable {
|
|||||||
*/
|
*/
|
||||||
fun <T : CharSequence> listOfNotEmpty(vararg elements: T): List<T> = elements.filterNot { it.isEmpty() }
|
fun <T : CharSequence> listOfNotEmpty(vararg elements: T): List<T> = elements.filterNot { it.isEmpty() }
|
||||||
|
|
||||||
fun List<CharSequence>.concat(delimiter: String? = null): CharSequence {
|
fun List<CharSequence?>.concat(delimiter: String? = null): CharSequence {
|
||||||
if (this.isEmpty()) {
|
if (this.isEmpty()) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.size == 1) {
|
if (this.size == 1) {
|
||||||
return this[0]
|
return this[0] ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var spanned = false
|
var spanned = false
|
||||||
@ -400,6 +399,8 @@ fun List<CharSequence>.concat(delimiter: String? = null): CharSequence {
|
|||||||
if (spanned) {
|
if (spanned) {
|
||||||
val ssb = SpannableStringBuilder()
|
val ssb = SpannableStringBuilder()
|
||||||
for (piece in this) {
|
for (piece in this) {
|
||||||
|
if (piece == null)
|
||||||
|
continue
|
||||||
if (!first && delimiter != null)
|
if (!first && delimiter != null)
|
||||||
ssb.append(delimiter)
|
ssb.append(delimiter)
|
||||||
first = false
|
first = false
|
||||||
@ -409,6 +410,8 @@ fun List<CharSequence>.concat(delimiter: String? = null): CharSequence {
|
|||||||
} else {
|
} else {
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
for (piece in this) {
|
for (piece in this) {
|
||||||
|
if (piece == null)
|
||||||
|
continue
|
||||||
if (!first && delimiter != null)
|
if (!first && delimiter != null)
|
||||||
sb.append(delimiter)
|
sb.append(delimiter)
|
||||||
first = false
|
first = false
|
||||||
@ -533,3 +536,54 @@ operator fun Time?.compareTo(other: Time?): Int {
|
|||||||
operator fun StringBuilder.plusAssign(str: String?) {
|
operator fun StringBuilder.plusAssign(str: String?) {
|
||||||
this.append(str)
|
this.append(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Context.timeTill(time: Int, delimiter: String = " "): String {
|
||||||
|
val parts = mutableListOf<Pair<Int, Int>>()
|
||||||
|
|
||||||
|
val hours = time / 3600
|
||||||
|
val minutes = (time - hours*3600) / 60
|
||||||
|
val seconds = time - minutes*60 - hours*3600
|
||||||
|
|
||||||
|
var prefixAdded = false
|
||||||
|
if (hours > 0) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_till_text to hours; prefixAdded = true
|
||||||
|
parts += R.plurals.time_till_hours to hours
|
||||||
|
}
|
||||||
|
if (minutes > 0) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_till_text to minutes; prefixAdded = true
|
||||||
|
parts += R.plurals.time_till_minutes to minutes
|
||||||
|
}
|
||||||
|
if (hours == 0 && minutes < 10) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_till_text to seconds; prefixAdded = true
|
||||||
|
parts += R.plurals.time_till_seconds to seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.timeLeft(time: Int, delimiter: String = " "): String {
|
||||||
|
val parts = mutableListOf<Pair<Int, Int>>()
|
||||||
|
|
||||||
|
val hours = time / 3600
|
||||||
|
val minutes = (time - hours*3600) / 60
|
||||||
|
val seconds = time - minutes*60 - hours*3600
|
||||||
|
|
||||||
|
var prefixAdded = false
|
||||||
|
if (hours > 0) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_left_text to hours
|
||||||
|
prefixAdded = true
|
||||||
|
parts += R.plurals.time_left_hours to hours
|
||||||
|
}
|
||||||
|
if (minutes > 0) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_left_text to minutes
|
||||||
|
prefixAdded = true
|
||||||
|
parts += R.plurals.time_left_minutes to minutes
|
||||||
|
}
|
||||||
|
if (hours == 0 && minutes < 10) {
|
||||||
|
if (!prefixAdded) parts += R.plurals.time_left_text to seconds
|
||||||
|
prefixAdded = true
|
||||||
|
parts += R.plurals.time_left_seconds to seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
||||||
|
}
|
||||||
|
@ -59,6 +59,11 @@ open class Lesson(val profileId: Int, @PrimaryKey var id: Long) {
|
|||||||
return startTime ?: oldStartTime
|
return startTime ?: oldStartTime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isCancelled
|
||||||
|
get() = type == TYPE_CANCELLED || type == TYPE_SHIFTED_SOURCE
|
||||||
|
val isChange
|
||||||
|
get() = type == TYPE_CHANGE || type == TYPE_SHIFTED_TARGET
|
||||||
|
|
||||||
fun buildId(): Long = (displayDate?.combineWith(displayStartTime) ?: 0L) / 6L * 10L + (hashCode() and 0xFFFF)
|
fun buildId(): Long = (displayDate?.combineWith(displayStartTime) ?: 0L) / 6L * 10L + (hashCode() and 0xFFFF)
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -110,7 +115,7 @@ open class Lesson(val profileId: Int, @PrimaryKey var id: Long) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int { // intentionally ignoring ID and display* here
|
||||||
var result = profileId
|
var result = profileId
|
||||||
result = 31 * result + type
|
result = 31 * result + type
|
||||||
result = 31 * result + (date?.hashCode() ?: 0)
|
result = 31 * result + (date?.hashCode() ?: 0)
|
||||||
@ -132,31 +137,3 @@ open class Lesson(val profileId: Int, @PrimaryKey var id: Long) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
DROP TABLE lessons;
|
|
||||||
DROP TABLE lessonChanges;
|
|
||||||
CREATE TABLE lessons (
|
|
||||||
profileId INTEGER NOT NULL,
|
|
||||||
type INTEGER NOT NULL,
|
|
||||||
|
|
||||||
date TEXT DEFAULT NULL,
|
|
||||||
lessonNumber INTEGER DEFAULT NULL,
|
|
||||||
startTime TEXT DEFAULT NULL,
|
|
||||||
endTime TEXT DEFAULT NULL,
|
|
||||||
teacherId INTEGER DEFAULT NULL,
|
|
||||||
subjectId INTEGER DEFAULT NULL,
|
|
||||||
teamId INTEGER DEFAULT NULL,
|
|
||||||
classroom TEXT DEFAULT NULL,
|
|
||||||
|
|
||||||
oldDate TEXT DEFAULT NULL,
|
|
||||||
oldLessonNumber INTEGER DEFAULT NULL,
|
|
||||||
oldStartTime TEXT DEFAULT NULL,
|
|
||||||
oldEndTime TEXT DEFAULT NULL,
|
|
||||||
oldTeacherId INTEGER DEFAULT NULL,
|
|
||||||
oldSubjectId INTEGER DEFAULT NULL,
|
|
||||||
oldTeamId INTEGER DEFAULT NULL,
|
|
||||||
oldClassroom TEXT DEFAULT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY(profileId)
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
@ -5,11 +5,15 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.core.view.plusAssign
|
import androidx.core.view.plusAssign
|
||||||
import androidx.core.view.setMargins
|
import androidx.core.view.setMargins
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
|
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||||
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
||||||
@ -22,6 +26,8 @@ import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
|||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2
|
||||||
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
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
import pl.szczodrzynski.navlib.colorAttr
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeTimetableCard(
|
class HomeTimetableCard(
|
||||||
@ -48,6 +54,17 @@ class HomeTimetableCard(
|
|||||||
private var lessons = listOf<LessonFull>()
|
private var lessons = listOf<LessonFull>()
|
||||||
private var events = listOf<Event>()
|
private var events = listOf<Event>()
|
||||||
|
|
||||||
|
private var bellSyncDiffMillis = 0L
|
||||||
|
private val syncedNow: Time
|
||||||
|
get() = Time.fromMillis(Time.getNow().inMillis + bellSyncDiffMillis)
|
||||||
|
|
||||||
|
private var counterJob: Job? = null
|
||||||
|
private var counterStart: Time? = null
|
||||||
|
private var counterEnd: Time? = null
|
||||||
|
private var subjectSpannable: CharSequence? = null
|
||||||
|
|
||||||
|
private val ignoreCancelled = true
|
||||||
|
|
||||||
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) {
|
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) {
|
||||||
holder.root.removeAllViews()
|
holder.root.removeAllViews()
|
||||||
b = CardHomeTimetableBinding.inflate(LayoutInflater.from(holder.root.context))
|
b = CardHomeTimetableBinding.inflate(LayoutInflater.from(holder.root.context))
|
||||||
@ -56,6 +73,17 @@ class HomeTimetableCard(
|
|||||||
}
|
}
|
||||||
holder.root += b.root
|
holder.root += b.root
|
||||||
|
|
||||||
|
b.settings.setImageDrawable(IconicsDrawable(activity, CommunityMaterial.Icon2.cmd_settings_outline)
|
||||||
|
.colorAttr(activity, R.attr.colorIcon)
|
||||||
|
.sizeDp(20))
|
||||||
|
|
||||||
|
// get current bell-sync params
|
||||||
|
if (app.appConfig.bellSyncDiff != null) {
|
||||||
|
bellSyncDiffMillis = (app.appConfig.bellSyncDiff.hour * 60 * 60 * 1000 + app.appConfig.bellSyncDiff.minute * 60 * 1000 + app.appConfig.bellSyncDiff.second * 1000).toLong()
|
||||||
|
bellSyncDiffMillis *= app.appConfig.bellSyncMultiplier.toLong()
|
||||||
|
bellSyncDiffMillis *= -1
|
||||||
|
}
|
||||||
|
|
||||||
// get all lessons within the search bounds
|
// get all lessons within the search bounds
|
||||||
app.db.timetableDao().getBetweenDates(today, searchEnd).observe(fragment, Observer {
|
app.db.timetableDao().getBetweenDates(today, searchEnd).observe(fragment, Observer {
|
||||||
allLessons = it
|
allLessons = it
|
||||||
@ -65,36 +93,177 @@ class HomeTimetableCard(
|
|||||||
|
|
||||||
private fun update() { launch {
|
private fun update() { launch {
|
||||||
val deferred = async(Dispatchers.Default) {
|
val deferred = async(Dispatchers.Default) {
|
||||||
// get current bell-sync params
|
|
||||||
var bellSyncDiffMillis: Long = 0
|
|
||||||
if (app.appConfig.bellSyncDiff != null) {
|
|
||||||
bellSyncDiffMillis = (app.appConfig.bellSyncDiff.hour * 60 * 60 * 1000 + app.appConfig.bellSyncDiff.minute * 60 * 1000 + app.appConfig.bellSyncDiff.second * 1000).toLong()
|
|
||||||
bellSyncDiffMillis *= app.appConfig.bellSyncMultiplier.toLong()
|
|
||||||
bellSyncDiffMillis *= -1
|
|
||||||
}
|
|
||||||
// get the current bell-synced time
|
// get the current bell-synced time
|
||||||
val now = Time.fromMillis(Time.getNow().inMillis + bellSyncDiffMillis)
|
val now = syncedNow
|
||||||
|
|
||||||
// search for lessons to display
|
// search for lessons to display
|
||||||
val timetableDate = Date.getToday()
|
val timetableDate = Date.getToday()
|
||||||
var checkedDays = 0
|
var checkedDays = 0
|
||||||
lessons = allLessons.filter { it.profileId == profile.id && it.displayDate == timetableDate && it.displayEndTime > now && it.type != Lesson.TYPE_NO_LESSONS }
|
lessons = allLessons.filter {
|
||||||
|
it.profileId == profile.id
|
||||||
|
&& it.displayDate == timetableDate
|
||||||
|
&& it.displayEndTime > now
|
||||||
|
&& it.type != Lesson.TYPE_NO_LESSONS
|
||||||
|
&& !(it.isCancelled && ignoreCancelled)
|
||||||
|
}
|
||||||
while ((lessons.isEmpty() || lessons.none {
|
while ((lessons.isEmpty() || lessons.none {
|
||||||
it.displayDate != today || (it.displayDate == today && it.displayEndTime != null && it.displayEndTime!! >= now)
|
it.displayDate != today || (it.displayDate == today && it.displayEndTime != null && it.displayEndTime!! >= now)
|
||||||
}) && checkedDays < 7) {
|
}) && checkedDays < 7) {
|
||||||
|
|
||||||
timetableDate.stepForward(0, 0, 1)
|
timetableDate.stepForward(0, 0, 1)
|
||||||
lessons = allLessons.filter { it.profileId == profile.id && it.displayDate == timetableDate && it.type != Lesson.TYPE_NO_LESSONS }
|
lessons = allLessons.filter {
|
||||||
|
it.profileId == profile.id
|
||||||
|
&& it.displayDate == timetableDate
|
||||||
|
&& it.type != Lesson.TYPE_NO_LESSONS
|
||||||
|
&& !(it.isCancelled && ignoreCancelled)
|
||||||
|
}
|
||||||
|
|
||||||
checkedDays++
|
checkedDays++
|
||||||
}
|
}
|
||||||
|
timetableDate
|
||||||
}
|
}
|
||||||
deferred.await()
|
val timetableDate = deferred.await()
|
||||||
|
|
||||||
val text = StringBuilder()
|
val isToday = today == timetableDate
|
||||||
for (lesson in lessons) {
|
|
||||||
text += lesson.displayStartTime?.stringHM+" "+lesson.displaySubjectName+"\n"
|
b.progress.visibility = View.GONE
|
||||||
|
b.counter.visibility = View.GONE
|
||||||
|
|
||||||
|
val now = syncedNow
|
||||||
|
val firstLesson = lessons.firstOrNull()
|
||||||
|
val lastLesson = lessons.lastOrNull()
|
||||||
|
|
||||||
|
if (isToday) {
|
||||||
|
// today
|
||||||
|
b.dayInfo.setText(R.string.home_timetable_today)
|
||||||
|
counterStart = firstLesson?.displayStartTime
|
||||||
|
counterEnd = firstLesson?.displayEndTime
|
||||||
|
val isOngoing = counterStart <= now && now <= counterEnd
|
||||||
|
val lessonRes = if (isOngoing)
|
||||||
|
R.string.home_timetable_lesson_ongoing
|
||||||
|
else
|
||||||
|
R.string.home_timetable_lesson_not_started
|
||||||
|
b.lessonBig.setText(lessonRes, firstLesson.subjectSpannable)
|
||||||
|
firstLesson?.displayClassroom?.let {
|
||||||
|
b.classroom.visibility = View.VISIBLE
|
||||||
|
b.classroom.text = it
|
||||||
|
} ?: run {
|
||||||
|
b.classroom.visibility = View.GONE
|
||||||
}
|
}
|
||||||
b.text.text = text.toString()
|
|
||||||
|
subjectSpannable = firstLesson.subjectSpannable
|
||||||
|
|
||||||
|
counterJob = startCoroutineTimer(repeatMillis = 1000) {
|
||||||
|
count()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val isTomorrow = today.clone().stepForward(0, 0, 1) == timetableDate
|
||||||
|
val dayInfoRes = if (isTomorrow) {
|
||||||
|
// tomorrow
|
||||||
|
R.string.home_timetable_tomorrow
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val todayWeekStart = today.weekStart
|
||||||
|
val dateWeekStart = timetableDate.weekStart
|
||||||
|
if (todayWeekStart == dateWeekStart) {
|
||||||
|
// this week
|
||||||
|
R.string.home_timetable_date_this_week
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// future: not this week
|
||||||
|
R.string.home_timetable_date_future
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.dayInfo.setText(dayInfoRes, Week.getFullDayName(timetableDate.weekDay), timetableDate.formattedString)
|
||||||
|
b.lessonInfo.setText(
|
||||||
|
R.string.home_timetable_lessons_info,
|
||||||
|
lessons.size,
|
||||||
|
firstLesson?.displayStartTime?.stringHM ?: "?",
|
||||||
|
lastLesson?.displayEndTime?.stringHM ?: "?"
|
||||||
|
)
|
||||||
|
|
||||||
|
b.lessonBig.setText(R.string.home_timetable_lesson_first, firstLesson.subjectSpannable)
|
||||||
|
firstLesson?.displayClassroom?.let {
|
||||||
|
b.classroom.visibility = View.VISIBLE
|
||||||
|
b.classroom.text = it
|
||||||
|
} ?: run {
|
||||||
|
b.classroom.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = mutableListOf<CharSequence>(
|
||||||
|
activity.getString(R.string.home_timetable_later)
|
||||||
|
)
|
||||||
|
var first = true
|
||||||
|
for (lesson in lessons) {
|
||||||
|
if (first) { first = false; continue }
|
||||||
|
text += listOf(
|
||||||
|
lesson.displayStartTime?.stringHM,
|
||||||
|
lesson.subjectSpannable
|
||||||
|
).concat(" ")
|
||||||
|
}
|
||||||
|
if (text.size == 1)
|
||||||
|
text += activity.getString(R.string.home_timetable_later_no_lessons)
|
||||||
|
b.nextLessons.text = text.concat("\n")
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
private val LessonFull?.subjectSpannable: CharSequence
|
||||||
|
get() = if (this == null) "?" else when {
|
||||||
|
isCancelled -> displaySubjectName.asStrikethroughSpannable()
|
||||||
|
isChange -> displaySubjectName.asItalicSpannable()
|
||||||
|
else -> displaySubjectName ?: "?"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun count() {
|
||||||
|
val counterStart = counterStart
|
||||||
|
val counterEnd = counterEnd
|
||||||
|
if (counterStart == null || counterEnd == null) {
|
||||||
|
// there is no lesson to count
|
||||||
|
b.progress.visibility = View.GONE
|
||||||
|
b.counter.visibility = View.GONE
|
||||||
|
this.counterJob?.cancel()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val now = syncedNow
|
||||||
|
if (now > counterEnd) {
|
||||||
|
// the lesson is already over
|
||||||
|
b.progress.visibility = View.GONE
|
||||||
|
b.counter.visibility = View.GONE
|
||||||
|
this.counterJob?.cancel()
|
||||||
|
this.counterStart = null
|
||||||
|
this.counterEnd = null
|
||||||
|
update() // check for new lessons to display
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val isOngoing = counterStart <= now && now <= counterEnd
|
||||||
|
val lessonRes = if (isOngoing)
|
||||||
|
R.string.home_timetable_lesson_ongoing
|
||||||
|
else
|
||||||
|
R.string.home_timetable_lesson_not_started
|
||||||
|
b.lessonBig.setText(lessonRes, subjectSpannable ?: "")
|
||||||
|
|
||||||
|
if (now < counterStart) {
|
||||||
|
// the lesson hasn't yet started
|
||||||
|
b.progress.visibility = View.GONE
|
||||||
|
b.counter.visibility = View.VISIBLE
|
||||||
|
val diff = counterStart - now
|
||||||
|
b.counter.text = activity.timeTill(diff.toInt(), "\n")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// the lesson is right now
|
||||||
|
b.progress.visibility = View.VISIBLE
|
||||||
|
b.counter.visibility = View.VISIBLE
|
||||||
|
val lessonLength = counterEnd - counterStart
|
||||||
|
val timePassed = now - counterStart
|
||||||
|
val timeLeft = counterEnd - now
|
||||||
|
b.counter.text = activity.timeLeft(timeLeft.toInt(), "\n")
|
||||||
|
b.progress.max = lessonLength.toInt()
|
||||||
|
b.progress.progress = timePassed.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) = Unit
|
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) = Unit
|
||||||
}
|
}
|
@ -3,6 +3,8 @@ package pl.szczodrzynski.edziennik.utils.models;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
public class Time implements Comparable<Time> {
|
public class Time implements Comparable<Time> {
|
||||||
@ -114,6 +116,10 @@ public class Time implements Comparable<Time> {
|
|||||||
return new Time(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND));
|
return new Time(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), c.get(Calendar.SECOND));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getInUnix() {
|
||||||
|
return getInMillis() / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
public int getValue()
|
public int getValue()
|
||||||
{
|
{
|
||||||
return hour * 10000 + minute * 100 + second;
|
return hour * 10000 + minute * 100 + second;
|
||||||
@ -202,4 +208,8 @@ public class Time implements Comparable<Time> {
|
|||||||
result = 31 * result + second;
|
result = 31 * result + second;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long minus(@NotNull Time other) {
|
||||||
|
return getInUnix() - other.getInUnix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,35 +12,10 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
tools:layout_margin="8dp">
|
tools:layout_margin="8dp">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView7"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/NavView.TextView.Title"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:text="Jutro" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/textView10"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textAppearance="@style/NavView.TextView.Helper"
|
|
||||||
android:visibility="gone"
|
|
||||||
tools:text="7 lekcji - 8:10 do 14:45" />
|
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginTop="4dp"
|
|
||||||
android:layout_marginBottom="4dp"
|
|
||||||
android:background="@color/dividerColor"
|
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal">
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@ -48,57 +23,100 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<ProgressBar
|
<TextView
|
||||||
android:id="@+id/progressBar4"
|
android:id="@+id/dayInfo"
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="4dp"
|
android:textAppearance="@style/NavView.TextView.Title"
|
||||||
android:layout_marginRight="4dp"
|
tools:text="Jutro" />
|
||||||
android:max="45"
|
|
||||||
android:progress="13"
|
|
||||||
tools:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView15"
|
android:id="@+id/lessonInfo"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/NavView.TextView.Small"
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
tools:text="09a komputerowa" />
|
tools:text="7 lekcji - 8:10 do 14:45" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/settings"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:src="@sample/settings" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:background="@color/dividerColor" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView12"
|
android:id="@+id/lessonBig"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/NavView.TextView.Subtitle"
|
android:textAppearance="@style/NavView.TextView.Subtitle"
|
||||||
tools:text="Pierwsza: informatyka" />
|
tools:text="Pierwsza: informatyka" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/classroom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Small"
|
||||||
|
tools:text="09a komputerowa" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/progress"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="4dp"
|
||||||
|
android:layout_marginRight="4dp"
|
||||||
|
android:max="2700"
|
||||||
|
android:progress="780" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textView13"
|
android:id="@+id/counter"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
tools:text="zostały\n32 minuty"
|
tools:text="zostały\n2 minuty\n35 sekund" />
|
||||||
tools:visibility="gone" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/view3"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:layout_marginTop="4dp"
|
android:layout_marginTop="4dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:background="@color/dividerColor"
|
android:background="@color/dividerColor" />
|
||||||
android:visibility="gone" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/nextLessons"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
tools:text="Póżniej:\n9:05 informatyka\n10:00 urządzenia techniki komputerowej\n11:00 projektowanie lokalnych sieci komputerowych\n11:55 zajęcia z wychowawcą\n13:00 język polski\n14:05 język niemiecki" />
|
tools:text="Póżniej:\n9:05 informatyka\n10:00 urządzenia techniki komputerowej\n11:00 projektowanie lokalnych sieci komputerowych\n11:55 zajęcia z wychowawcą\n13:00 język polski\n14:05 język niemiecki" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -8,4 +8,5 @@
|
|||||||
<attr name="timetable_lesson_change_color" format="color" />
|
<attr name="timetable_lesson_change_color" format="color" />
|
||||||
<attr name="timetable_lesson_shifted_source_color" format="color" />
|
<attr name="timetable_lesson_shifted_source_color" format="color" />
|
||||||
<attr name="timetable_lesson_shifted_target_color" format="color" />
|
<attr name="timetable_lesson_shifted_target_color" format="color" />
|
||||||
|
<attr name="colorIcon" format="color" />
|
||||||
</resources>
|
</resources>
|
@ -1044,4 +1044,14 @@
|
|||||||
<string name="home_lucky_number_today">%d to dzisiejszy szczęśliwy numerek.</string>
|
<string name="home_lucky_number_today">%d to dzisiejszy szczęśliwy numerek.</string>
|
||||||
<string name="home_lucky_number_tomorrow">%d to szczęśliwy numerek na jutro.</string>
|
<string name="home_lucky_number_tomorrow">%d to szczęśliwy numerek na jutro.</string>
|
||||||
<string name="home_lucky_number_no_number">Nie ma dzisiaj szczęśliwego numerka.</string>
|
<string name="home_lucky_number_no_number">Nie ma dzisiaj szczęśliwego numerka.</string>
|
||||||
|
<string name="home_timetable_tomorrow">Jutro (%1$s)</string>
|
||||||
|
<string name="home_timetable_date_this_week">%1$s, %2$s</string>
|
||||||
|
<string name="home_timetable_date_future">%1$s, %2$s</string>
|
||||||
|
<string name="home_timetable_lessons_info">%d lekcji - %s do %s</string>
|
||||||
|
<string name="home_timetable_lesson_first">Pierwsza: %s</string>
|
||||||
|
<string name="home_timetable_later">Później:</string>
|
||||||
|
<string name="home_timetable_later_no_lessons">brak lekcji</string>
|
||||||
|
<string name="home_timetable_today">Dzisiaj</string>
|
||||||
|
<string name="home_timetable_lesson_ongoing">Teraz: %s</string>
|
||||||
|
<string name="home_timetable_lesson_not_started">Za chwilę: %s</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
<item name="colorFab">#4CAF50</item>
|
<item name="colorFab">#4CAF50</item>
|
||||||
<item name="colorFabIcon">#c8e6c9</item>
|
<item name="colorFabIcon">#c8e6c9</item>
|
||||||
<item name="colorOnFab">#ffffff</item>
|
<item name="colorOnFab">#ffffff</item>
|
||||||
|
<item name="colorIcon">#8a000000</item>
|
||||||
|
|
||||||
<item name="md_dark_theme">false</item>
|
<item name="md_dark_theme">false</item>
|
||||||
<item name="md_title_color">?android:textColorPrimary</item>
|
<item name="md_title_color">?android:textColorPrimary</item>
|
||||||
@ -114,6 +115,7 @@
|
|||||||
<item name="colorFab">#4CAF50</item>
|
<item name="colorFab">#4CAF50</item>
|
||||||
<item name="colorFabIcon">#c8e6c9</item>
|
<item name="colorFabIcon">#c8e6c9</item>
|
||||||
<item name="colorOnFab">#ffffff</item>
|
<item name="colorOnFab">#ffffff</item>
|
||||||
|
<item name="colorIcon">#b4ffffff</item>
|
||||||
|
|
||||||
<item name="md_dark_theme">true</item>
|
<item name="md_dark_theme">true</item>
|
||||||
<item name="md_title_color">?android:textColorPrimary</item>
|
<item name="md_title_color">?android:textColorPrimary</item>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user