forked from github/szkolny
[UI/Counter] Add new counter activity.
This commit is contained in:
parent
62a9604bd2
commit
e85d6fbc3b
@ -116,6 +116,9 @@
|
|||||||
android:name=".ui.modules.webpush.WebPushConfigActivity"
|
android:name=".ui.modules.webpush.WebPushConfigActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:theme="@style/AppTheme.Dark" />
|
android:theme="@style/AppTheme.Dark" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.modules.home.CounterActivityOld"
|
||||||
|
android:theme="@style/AppTheme.Black" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.modules.home.CounterActivity"
|
android:name=".ui.modules.home.CounterActivity"
|
||||||
android:theme="@style/AppTheme.Black" />
|
android:theme="@style/AppTheme.Black" />
|
||||||
|
@ -576,37 +576,46 @@ operator fun StringBuilder.plusAssign(str: String?) {
|
|||||||
this.append(str)
|
this.append(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.timeTill(time: Int, delimiter: String = " "): String {
|
fun Context.timeTill(time: Int, delimiter: String = " ", countInSeconds: Boolean = false): String {
|
||||||
val parts = mutableListOf<Pair<Int, Int>>()
|
val parts = mutableListOf<Pair<Int, Int>>()
|
||||||
|
|
||||||
val hours = time / 3600
|
val hours = time / 3600
|
||||||
val minutes = (time - hours*3600) / 60
|
val minutes = (time - hours*3600) / 60
|
||||||
val seconds = time - minutes*60 - hours*3600
|
val seconds = time - minutes*60 - hours*3600
|
||||||
|
|
||||||
|
if (!countInSeconds) {
|
||||||
var prefixAdded = false
|
var prefixAdded = false
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
if (!prefixAdded) parts += R.plurals.time_till_text to hours; prefixAdded = true
|
if (!prefixAdded) parts += R.plurals.time_till_text to hours
|
||||||
|
prefixAdded = true
|
||||||
parts += R.plurals.time_till_hours to hours
|
parts += R.plurals.time_till_hours to hours
|
||||||
}
|
}
|
||||||
if (minutes > 0) {
|
if (minutes > 0) {
|
||||||
if (!prefixAdded) parts += R.plurals.time_till_text to minutes; prefixAdded = true
|
if (!prefixAdded) parts += R.plurals.time_till_text to minutes
|
||||||
|
prefixAdded = true
|
||||||
parts += R.plurals.time_till_minutes to minutes
|
parts += R.plurals.time_till_minutes to minutes
|
||||||
}
|
}
|
||||||
if (hours == 0 && minutes < 10) {
|
if (hours == 0 && minutes < 10) {
|
||||||
if (!prefixAdded) parts += R.plurals.time_till_text to seconds; prefixAdded = true
|
if (!prefixAdded) parts += R.plurals.time_till_text to seconds
|
||||||
|
prefixAdded = true
|
||||||
parts += R.plurals.time_till_seconds to seconds
|
parts += R.plurals.time_till_seconds to seconds
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
parts += R.plurals.time_till_text to time
|
||||||
|
parts += R.plurals.time_till_seconds to time
|
||||||
|
}
|
||||||
|
|
||||||
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.timeLeft(time: Int, delimiter: String = " "): String {
|
fun Context.timeLeft(time: Int, delimiter: String = " ", countInSeconds: Boolean = false): String {
|
||||||
val parts = mutableListOf<Pair<Int, Int>>()
|
val parts = mutableListOf<Pair<Int, Int>>()
|
||||||
|
|
||||||
val hours = time / 3600
|
val hours = time / 3600
|
||||||
val minutes = (time - hours*3600) / 60
|
val minutes = (time - hours*3600) / 60
|
||||||
val seconds = time - minutes*60 - hours*3600
|
val seconds = time - minutes*60 - hours*3600
|
||||||
|
|
||||||
|
if (!countInSeconds) {
|
||||||
var prefixAdded = false
|
var prefixAdded = false
|
||||||
if (hours > 0) {
|
if (hours > 0) {
|
||||||
if (!prefixAdded) parts += R.plurals.time_left_text to hours
|
if (!prefixAdded) parts += R.plurals.time_left_text to hours
|
||||||
@ -623,6 +632,10 @@ fun Context.timeLeft(time: Int, delimiter: String = " "): String {
|
|||||||
prefixAdded = true
|
prefixAdded = true
|
||||||
parts += R.plurals.time_left_seconds to seconds
|
parts += R.plurals.time_left_seconds to seconds
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
parts += R.plurals.time_left_text to time
|
||||||
|
parts += R.plurals.time_left_seconds to time
|
||||||
|
}
|
||||||
|
|
||||||
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
return parts.joinToString(delimiter) { resources.getQuantityString(it.first, it.second, it.second) }
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import kotlinx.coroutines.*
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding
|
||||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
@ -103,18 +104,23 @@ class BellSyncTimeChooseDialog(
|
|||||||
val items = mutableListOf<TextInputDropDown.Item>()
|
val items = mutableListOf<TextInputDropDown.Item>()
|
||||||
|
|
||||||
lessons.forEach {
|
lessons.forEach {
|
||||||
|
if (it.type != Lesson.TYPE_NO_LESSONS &&
|
||||||
|
it.type != Lesson.TYPE_CANCELLED &&
|
||||||
|
it.type != Lesson.TYPE_SHIFTED_SOURCE) {
|
||||||
|
|
||||||
items += TextInputDropDown.Item(
|
items += TextInputDropDown.Item(
|
||||||
it.startTime?.value?.toLong() ?: return@forEach,
|
it.displayStartTime?.value?.toLong() ?: return@forEach,
|
||||||
app.getString(R.string.bell_sync_lesson_item, it.displaySubjectName, it.startTime?.stringHM),
|
app.getString(R.string.bell_sync_lesson_item, it.displaySubjectName, it.displayStartTime?.stringHM),
|
||||||
tag = it.startTime
|
tag = it.displayStartTime
|
||||||
)
|
)
|
||||||
|
|
||||||
items += TextInputDropDown.Item(
|
items += TextInputDropDown.Item(
|
||||||
it.endTime?.value?.toLong() ?: return@forEach,
|
it.displayEndTime?.value?.toLong() ?: return@forEach,
|
||||||
app.getString(R.string.bell_sync_break_item, it.endTime?.stringHM),
|
app.getString(R.string.bell_sync_break_item, it.displayEndTime?.stringHM),
|
||||||
tag = it.endTime
|
tag = it.displayEndTime
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2019-12-21
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.ActivityCounterBinding
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class CounterActivity : AppCompatActivity(), CoroutineScope {
|
||||||
|
|
||||||
|
private var job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private var counterJob: Job? = null
|
||||||
|
|
||||||
|
private val app by lazy { application as App }
|
||||||
|
private lateinit var b: ActivityCounterBinding
|
||||||
|
|
||||||
|
private val lessonList = mutableListOf<LessonFull>()
|
||||||
|
|
||||||
|
private var bellSyncDiffMillis = 0L
|
||||||
|
private val syncedNow: Time
|
||||||
|
get() = Time.fromMillis(Time.getNow().inMillis - bellSyncDiffMillis)
|
||||||
|
|
||||||
|
private val countInSeconts: Boolean
|
||||||
|
get() = app.config.timetable.countInSeconds
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
b = ActivityCounterBinding.inflate(layoutInflater)
|
||||||
|
setContentView(b.root)
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() { launch {
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
lessonList.apply {
|
||||||
|
clear()
|
||||||
|
addAll(app.db.timetableDao().getForDateNow(App.profileId, Date.getToday())
|
||||||
|
.filter {
|
||||||
|
it.type != Lesson.TYPE_NO_LESSONS && it.type != Lesson.TYPE_CANCELLED &&
|
||||||
|
it.type != Lesson.TYPE_SHIFTED_SOURCE
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.timetable.bellSyncDiff?.let {
|
||||||
|
bellSyncDiffMillis = (it.hour * 60 * 60 * 1000 + it.minute * 60 * 1000 + it.second * 1000).toLong()
|
||||||
|
bellSyncDiffMillis *= app.config.timetable.bellSyncMultiplier.toLong()
|
||||||
|
}
|
||||||
|
|
||||||
|
counterJob = startCoroutineTimer(repeatMillis = 1000) {
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
private fun update() {
|
||||||
|
if (lessonList.isEmpty()) {
|
||||||
|
b.lessonName.text = app.getString(R.string.no_lessons_today)
|
||||||
|
b.timeLeft.text = ""
|
||||||
|
} else {
|
||||||
|
val now = syncedNow
|
||||||
|
|
||||||
|
val next = lessonList.firstOrNull {
|
||||||
|
it.displayStartTime != null && it.displayStartTime!! > now
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = lessonList.firstOrNull {
|
||||||
|
it.displayStartTime != null && it.displayEndTime != null &&
|
||||||
|
it.displayStartTime!! <= now && now <= it.displayEndTime!!
|
||||||
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
actual != null -> {
|
||||||
|
b.lessonName.text = actual.displaySubjectName
|
||||||
|
|
||||||
|
val left = actual.displayEndTime!! - now
|
||||||
|
b.timeLeft.text = timeLeft(left.toInt(), "\n", countInSeconts)
|
||||||
|
}
|
||||||
|
next != null -> {
|
||||||
|
b.lessonName.text = next.displaySubjectName
|
||||||
|
|
||||||
|
val till = next.displayStartTime!! - now
|
||||||
|
b.timeLeft.text = timeTill(till.toInt(), "\n", countInSeconts)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
b.lessonName.text = app.getString(R.string.lessons_finished)
|
||||||
|
b.timeLeft.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
counterJob?.cancel()
|
||||||
|
}
|
||||||
|
}
|
@ -22,9 +22,9 @@ import pl.szczodrzynski.edziennik.utils.models.Time;
|
|||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentOld.updateInterval;
|
import static pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentOld.updateInterval;
|
||||||
|
|
||||||
public class CounterActivity extends AppCompatActivity {
|
public class CounterActivityOld extends AppCompatActivity {
|
||||||
|
|
||||||
private static final String TAG = "CounterActivity";
|
private static final String TAG = "CounterActivityOld";
|
||||||
private App app;
|
private App app;
|
||||||
private ActivityCounterBinding b;
|
private ActivityCounterBinding b;
|
||||||
|
|
@ -61,7 +61,7 @@ public class HomeTimetableCardOld {
|
|||||||
insertPoint.addView(b.getRoot(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
insertPoint.addView(b.getRoot(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
b.cardTimetableFullscreenCounter.setOnClickListener((v -> {
|
b.cardTimetableFullscreenCounter.setOnClickListener((v -> {
|
||||||
Intent intent = new Intent(a, CounterActivity.class);
|
Intent intent = new Intent(a, CounterActivityOld.class);
|
||||||
a.startActivity(intent);
|
a.startActivity(intent);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -30,6 +31,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
|||||||
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding
|
import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncTimeChooseDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncTimeChooseDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.CounterActivity
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment
|
||||||
@ -66,7 +68,7 @@ class HomeTimetableCard(
|
|||||||
|
|
||||||
private var bellSyncDiffMillis = 0L
|
private var bellSyncDiffMillis = 0L
|
||||||
private val syncedNow: Time
|
private val syncedNow: Time
|
||||||
get() = Time.fromMillis(Time.getNow().inMillis + bellSyncDiffMillis)
|
get() = Time.fromMillis(Time.getNow().inMillis - bellSyncDiffMillis)
|
||||||
|
|
||||||
private var counterJob: Job? = null
|
private var counterJob: Job? = null
|
||||||
private var counterStart: Time? = null
|
private var counterStart: Time? = null
|
||||||
@ -91,12 +93,20 @@ class HomeTimetableCard(
|
|||||||
.colorAttr(activity, R.attr.colorIcon)
|
.colorAttr(activity, R.attr.colorIcon)
|
||||||
.sizeDp(20))
|
.sizeDp(20))
|
||||||
|
|
||||||
|
b.showCounter.setImageDrawable(IconicsDrawable(activity, CommunityMaterial.Icon.cmd_fullscreen)
|
||||||
|
.colorAttr(activity, R.attr.colorIcon)
|
||||||
|
.sizeDp(20))
|
||||||
|
|
||||||
b.bellSync.setOnClickListener {
|
b.bellSync.setOnClickListener {
|
||||||
BellSyncTimeChooseDialog(
|
BellSyncTimeChooseDialog(
|
||||||
activity
|
activity
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.showCounter.setOnClickListener {
|
||||||
|
activity.startActivity(Intent(activity, CounterActivity::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
b.root.onClick {
|
b.root.onClick {
|
||||||
activity.loadTarget(MainActivity.DRAWER_ITEM_TIMETABLE, Bundle().apply {
|
activity.loadTarget(MainActivity.DRAWER_ITEM_TIMETABLE, Bundle().apply {
|
||||||
putString("timetableDate", timetableDate.stringY_m_d)
|
putString("timetableDate", timetableDate.stringY_m_d)
|
||||||
@ -113,7 +123,6 @@ class HomeTimetableCard(
|
|||||||
app.config.timetable.bellSyncDiff?.let {
|
app.config.timetable.bellSyncDiff?.let {
|
||||||
bellSyncDiffMillis = (it.hour * 60 * 60 * 1000 + it.minute * 60 * 1000 + it.second * 1000).toLong()
|
bellSyncDiffMillis = (it.hour * 60 * 60 * 1000 + it.minute * 60 * 1000 + it.second * 1000).toLong()
|
||||||
bellSyncDiffMillis *= app.config.timetable.bellSyncMultiplier.toLong()
|
bellSyncDiffMillis *= app.config.timetable.bellSyncMultiplier.toLong()
|
||||||
bellSyncDiffMillis *= -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get all lessons within the search bounds
|
// get all lessons within the search bounds
|
||||||
|
@ -183,6 +183,14 @@
|
|||||||
android:padding="10dp"
|
android:padding="10dp"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
tools:src="@sample/settings" />
|
tools:src="@sample/settings" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/showCounter"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:padding="10dp"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
|
tools:src="@sample/settings" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
@ -1124,4 +1124,6 @@
|
|||||||
<string name="widget_timetable_no_lessons_found">Brak lekcji przez następne 7 dni.</string>
|
<string name="widget_timetable_no_lessons_found">Brak lekcji przez następne 7 dni.</string>
|
||||||
<string name="widget_timetable_short_no_timetable">Nie pobrano planu lekcji.</string>
|
<string name="widget_timetable_short_no_timetable">Nie pobrano planu lekcji.</string>
|
||||||
<string name="widget_timetable_short_no_lessons">Brak lekcji przez nast. 7 dni.</string>
|
<string name="widget_timetable_short_no_lessons">Brak lekcji przez nast. 7 dni.</string>
|
||||||
|
<string name="no_lessons_today">Nie ma dzisiaj żadnych lekcji!</string>
|
||||||
|
<string name="lessons_finished">Nie ma dzisiaj więcej lekcji!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user