[UI] Implement home timetable card.

This commit is contained in:
Kuba Szczodrzyński 2019-11-25 22:15:36 +01:00
parent 7961a74995
commit 37f3d76fb8
9 changed files with 348 additions and 94 deletions

View 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>

View File

@ -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) }
}

View File

@ -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)
@ -131,32 +136,4 @@ open class Lesson(val profileId: Int, @PrimaryKey var id: Long) {
result = 31 * result + (oldClassroom?.hashCode() ?: 0) result = 31 * result + (oldClassroom?.hashCode() ?: 0)
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)
);
*/

View File

@ -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
}
subjectSpannable = firstLesson.subjectSpannable
counterJob = startCoroutineTimer(repeatMillis = 1000) {
count()
}
} }
b.text.text = text.toString() 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
} }

View File

@ -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();
}
} }

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>