forked from github/szkolny
[Home] Implement basic timetable card.
This commit is contained in:
parent
867c8920a8
commit
f116c4f1f4
@ -35,6 +35,7 @@ import kotlinx.coroutines.launch
|
|||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
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.navlib.R
|
import pl.szczodrzynski.navlib.R
|
||||||
import pl.szczodrzynski.navlib.getColorFromRes
|
import pl.szczodrzynski.navlib.getColorFromRes
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@ -518,3 +519,17 @@ fun CoroutineScope.startCoroutineTimer(delayMillis: Long = 0, repeatMillis: Long
|
|||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
operator fun Time?.compareTo(other: Time?): Int {
|
||||||
|
if (this == null && other == null)
|
||||||
|
return 0
|
||||||
|
if (this == null)
|
||||||
|
return -1
|
||||||
|
if (other == null)
|
||||||
|
return 1
|
||||||
|
return this.compareTo(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun StringBuilder.plusAssign(str: String?) {
|
||||||
|
this.append(str)
|
||||||
|
}
|
||||||
|
@ -75,6 +75,13 @@ interface TimetableDao {
|
|||||||
""")
|
""")
|
||||||
fun getBetweenDatesNow(dateFrom: Date, dateTo: Date) : List<LessonFull>
|
fun getBetweenDatesNow(dateFrom: Date, dateTo: Date) : List<LessonFull>
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
$QUERY
|
||||||
|
WHERE (type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo)
|
||||||
|
ORDER BY profileId, id, type
|
||||||
|
""")
|
||||||
|
fun getBetweenDates(dateFrom: Date, dateTo: Date) : LiveData<List<LessonFull>>
|
||||||
|
|
||||||
@Query("""
|
@Query("""
|
||||||
$QUERY
|
$QUERY
|
||||||
WHERE timetable.profileId = :profileId AND timetable.id = :lessonId
|
WHERE timetable.profileId = :profileId AND timetable.id = :lessonId
|
||||||
|
@ -4,10 +4,13 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.modules.home
|
package pl.szczodrzynski.edziennik.ui.modules.home
|
||||||
|
|
||||||
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.OnClickListener
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.core.view.AccessibilityDelegateCompat
|
import androidx.core.view.AccessibilityDelegateCompat
|
||||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
||||||
@ -15,6 +18,8 @@ import androidx.fragment.app.Fragment
|
|||||||
import androidx.recyclerview.widget.ItemTouchHelper
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate
|
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate
|
||||||
|
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial.Icon
|
||||||
|
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
@ -22,8 +27,12 @@ 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.databinding.FragmentHomeV2Binding
|
import pl.szczodrzynski.edziennik.databinding.FragmentHomeV2Binding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.home.StudentNumberDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeLuckyNumberCard
|
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeLuckyNumberCard
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.cards.HomeTimetableCard
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
|
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||||
|
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class HomeFragmentV2 : Fragment(), CoroutineScope {
|
class HomeFragmentV2 : Fragment(), CoroutineScope {
|
||||||
@ -62,8 +71,30 @@ class HomeFragmentV2 : Fragment(), CoroutineScope {
|
|||||||
if (app.profile == null || !isAdded)
|
if (app.profile == null || !isAdded)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
activity.bottomSheet.prependItems(
|
||||||
|
BottomSheetPrimaryItem(true)
|
||||||
|
.withTitle(R.string.menu_set_student_number)
|
||||||
|
.withIcon(SzkolnyFont.Icon.szf_clipboard_list_outline)
|
||||||
|
.withOnClickListener(OnClickListener {
|
||||||
|
activity.bottomSheet.close()
|
||||||
|
StudentNumberDialog(activity, app.profile) {
|
||||||
|
app.profileSaveAsync()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
BottomSheetSeparatorItem(true),
|
||||||
|
BottomSheetPrimaryItem(true)
|
||||||
|
.withTitle(R.string.menu_mark_everything_as_read)
|
||||||
|
.withIcon(Icon.cmd_eye_check_outline)
|
||||||
|
.withOnClickListener(OnClickListener {
|
||||||
|
activity.bottomSheet.close()
|
||||||
|
AsyncTask.execute { app.db.metadataDao().setAllSeen(App.profileId, true) }
|
||||||
|
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
val items = mutableListOf<HomeCard>(
|
val items = mutableListOf<HomeCard>(
|
||||||
HomeLuckyNumberCard(0, app, activity, this, app.profile),
|
HomeLuckyNumberCard(0, app, activity, this, app.profile),
|
||||||
|
HomeTimetableCard(0, app, activity, this, app.profile),
|
||||||
HomeDummyCard(1),
|
HomeDummyCard(1),
|
||||||
HomeDummyCard(2),
|
HomeDummyCard(2),
|
||||||
HomeDummyCard(3),
|
HomeDummyCard(3),
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.home.cards
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
|
import androidx.core.view.plusAssign
|
||||||
|
import androidx.core.view.setMargins
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull
|
||||||
|
import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
class HomeTimetableCard(
|
||||||
|
val id: Int,
|
||||||
|
val app: App,
|
||||||
|
val activity: MainActivity,
|
||||||
|
val fragment: HomeFragmentV2,
|
||||||
|
val profile: Profile
|
||||||
|
) : HomeCard, CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "HomeTimetableCard"
|
||||||
|
}
|
||||||
|
|
||||||
|
private var job: Job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private lateinit var b: CardHomeTimetableBinding
|
||||||
|
|
||||||
|
private val today = Date.getToday()
|
||||||
|
private val searchEnd = today.clone().stepForward(0, 0, 7)
|
||||||
|
|
||||||
|
private var allLessons = listOf<LessonFull>()
|
||||||
|
private var lessons = listOf<LessonFull>()
|
||||||
|
private var events = listOf<Event>()
|
||||||
|
|
||||||
|
override fun bind(position: Int, holder: HomeCardAdapter.ViewHolder) {
|
||||||
|
holder.root.removeAllViews()
|
||||||
|
b = CardHomeTimetableBinding.inflate(LayoutInflater.from(holder.root.context))
|
||||||
|
b.root.layoutParams = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT).apply {
|
||||||
|
setMargins(8.dp)
|
||||||
|
}
|
||||||
|
holder.root += b.root
|
||||||
|
|
||||||
|
// get all lessons within the search bounds
|
||||||
|
app.db.timetableDao().getBetweenDates(today, searchEnd).observe(fragment, Observer {
|
||||||
|
allLessons = it
|
||||||
|
update()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun update() { launch {
|
||||||
|
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
|
||||||
|
val now = Time.fromMillis(Time.getNow().inMillis + bellSyncDiffMillis)
|
||||||
|
|
||||||
|
// search for lessons to display
|
||||||
|
val timetableDate = Date.getToday()
|
||||||
|
var checkedDays = 0
|
||||||
|
lessons = allLessons.filter { it.profileId == profile.id && it.displayDate == timetableDate && it.displayEndTime > now && it.type != Lesson.TYPE_NO_LESSONS }
|
||||||
|
while ((lessons.isEmpty() || lessons.none {
|
||||||
|
it.displayDate != today || (it.displayDate == today && it.displayEndTime != null && it.displayEndTime!! >= now)
|
||||||
|
}) && checkedDays < 7) {
|
||||||
|
timetableDate.stepForward(0, 0, 1)
|
||||||
|
lessons = allLessons.filter { it.profileId == profile.id && it.displayDate == timetableDate && it.type != Lesson.TYPE_NO_LESSONS }
|
||||||
|
checkedDays++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deferred.await()
|
||||||
|
|
||||||
|
val text = StringBuilder()
|
||||||
|
for (lesson in lessons) {
|
||||||
|
text += lesson.displayStartTime?.stringHM+" "+lesson.displaySubjectName+"\n"
|
||||||
|
}
|
||||||
|
b.text.text = text.toString()
|
||||||
|
}}
|
||||||
|
|
||||||
|
override fun unbind(position: Int, holder: HomeCardAdapter.ViewHolder) = Unit
|
||||||
|
}
|
@ -11,7 +11,4 @@
|
|||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true">
|
android:focusable="true" />
|
||||||
|
|
||||||
<include layout="@layout/card_home_lucky_number" />
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?><!--
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -30,8 +31,8 @@
|
|||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:layout_marginLeft="8dp"
|
||||||
android:textAppearance="@style/NavView.TextView.Title"
|
android:text="@string/home_lucky_number_no_info"
|
||||||
android:text="@string/home_lucky_number_no_info" />
|
android:textAppearance="@style/NavView.TextView.Title" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
21
app/src/main/res/layout/card_home_timetable.xml
Normal file
21
app/src/main/res/layout/card_home_timetable.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (c) Kuba Szczodrzyński 2019-11-24.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:layout_margin="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
Loading…
x
Reference in New Issue
Block a user