[UI] Update manual event dialog. Fix timetable errors.

This commit is contained in:
Kuba Szczodrzyński 2019-11-20 21:13:43 +01:00
parent 9866017f7e
commit 62fdfa2b6f
8 changed files with 413 additions and 265 deletions

View File

@ -39,6 +39,9 @@ const val ERROR_REQUEST_HTTP_404 = 54
const val ERROR_REQUEST_HTTP_405 = 55
const val ERROR_REQUEST_HTTP_410 = 56
const val ERROR_REQUEST_HTTP_500 = 57
const val ERROR_REQUEST_FAILURE_HOSTNAME_NOT_FOUND = 60
const val ERROR_REQUEST_FAILURE_TIMEOUT = 61
const val ERROR_REQUEST_FAILURE_NO_INTERNET = 62
const val ERROR_RESPONSE_EMPTY = 100
const val ERROR_LOGIN_DATA_MISSING = 101
const val ERROR_PROFILE_MISSING = 105

View File

@ -47,7 +47,7 @@ interface TimetableDao {
@Query("""
$QUERY
WHERE timetable.profileId = :profileId AND (type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date)
WHERE timetable.profileId = :profileId AND ((type != 3 AND date = :date) OR ((type = 3 OR type = 1) AND oldDate = :date))
ORDER BY id, type
""")
fun getForDate(profileId: Int, date: Date) : LiveData<List<LessonFull>>
@ -58,7 +58,7 @@ interface TimetableDao {
ORDER BY id, type
LIMIT 1
""")
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData<LessonFull>
fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData<LessonFull?>
@Query("""
$QUERY

View File

@ -4,19 +4,25 @@
package pl.szczodrzynski.edziennik.ui.dialogs.event
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
import pl.szczodrzynski.edziennik.data.db.modules.events.EventType
import pl.szczodrzynski.edziennik.data.db.modules.subjects.Subject
import pl.szczodrzynski.edziennik.data.db.modules.teams.Team
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
import pl.szczodrzynski.edziennik.utils.Anim
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@ -46,9 +52,11 @@ class EventManualV2Dialog(
private val app by lazy { activity.application as App }
private lateinit var b: DialogEventManualV2Binding
private lateinit var dialog: AlertDialog
private lateinit var event: Event
private var defaultLoaded = false
private lateinit var event: Event
private var customColor: Int? = null
init { run {
if (activity.isFinishing)
return@run
@ -80,6 +88,17 @@ class EventManualV2Dialog(
}*/
}
b.showMore.onClick { // TODO iconics is broken
it.apply {
refreshDrawableState()
if (isChecked)
Anim.expand(b.moreLayout, 200, null)
else
Anim.collapse(b.moreLayout, 200, null)
}
}
loadLists()
}}
@ -114,18 +133,33 @@ class EventManualV2Dialog(
""
)
b.teacherDropdown += teachers.map { TextInputDropDown.Item(it.id, it.fullName, tag = it) }
// get the event type list
val eventTypes = app.db.eventTypeDao().getAllNow(profileId)
b.typeDropdown.clear()
b.typeDropdown += eventTypes.map { TextInputDropDown.Item(it.id, it.name, tag = it) }
}
deferred.await()
b.teamDropdown.isEnabled = true
b.subjectDropdown.isEnabled = true
b.teacherDropdown.isEnabled = true
b.typeDropdown.isEnabled = true
b.typeDropdown.selected?.let { item ->
customColor = (item.tag as EventType).color
}
// copy IDs from event being edited
editingEvent?.let {
b.teamDropdown.select(it.teamId)
b.subjectDropdown.select(it.subjectId)
b.teacherDropdown.select(it.teacherId)
b.typeDropdown.select(it.type)?.let { item ->
customColor = (item.tag as EventType).color
}
if (it.color != -1)
customColor = it.color
}
// copy IDs from the LessonFull
@ -135,6 +169,30 @@ class EventManualV2Dialog(
b.teacherDropdown.select(it.displayTeacherId)
}
b.typeDropdown.setOnChangeListener {
b.typeDropdown.background.colorFilter = PorterDuffColorFilter((it.tag as EventType).color, PorterDuff.Mode.SRC_ATOP)
customColor = null
return@setOnChangeListener true
}
customColor?.let {
b.typeDropdown.background.colorFilter = PorterDuffColorFilter(it, PorterDuff.Mode.SRC_ATOP)
}
b.typeColor.onClick {
val currentColor = (b.typeDropdown?.selected?.tag as EventType?)?.color ?: Event.COLOR_DEFAULT
val colorPickerDialog = ColorPickerDialog.newBuilder()
.setColor(currentColor)
.create()
colorPickerDialog.setColorPickerDialogListener(
object : ColorPickerDialogListener {
override fun onDialogDismissed(dialogId: Int) {}
override fun onColorSelected(dialogId: Int, color: Int) {
b.typeDropdown.background.colorFilter = PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
customColor = color
}
})
colorPickerDialog.show(activity.fragmentManager, "color-picker-dialog")
}
loadDates()
}}
@ -205,12 +263,20 @@ class EventManualV2Dialog(
val dates = deferred.await()
b.dateDropdown.clear().append(dates)
editingEvent?.let {
b.dateDropdown.select(it.eventDate.value.toLong())
editingEvent?.eventDate?.let {
b.dateDropdown.select(TextInputDropDown.Item(
it.value.toLong(),
it.formattedString,
tag = it
))
}
defaultLesson?.let {
b.dateDropdown.select(it.displayDate?.value?.toLong())
defaultLesson?.displayDate?.let {
b.dateDropdown.select(TextInputDropDown.Item(
it.value.toLong(),
it.formattedString,
tag = it
))
}
if (b.dateDropdown.selected == null) {
@ -223,22 +289,19 @@ class EventManualV2Dialog(
when {
// next lesson with specified subject
item.id < -1 -> {
// TODO include lesson team in search
app.db.timetableDao().getNextWithSubject(profileId, Date.getToday(), -item.id).observeOnce(activity, Observer {
val lessonDate = it?.displayDate ?: return@Observer
b.dateDropdown.selected = TextInputDropDown.Item(
b.dateDropdown.select(TextInputDropDown.Item(
lessonDate.value.toLong(),
lessonDate.formattedString,
tag = lessonDate
)
// TODO load correct hour when selecting next lesson
b.dateDropdown.updateText()
it.let {
))
b.teamDropdown.select(it.displayTeamId)
b.subjectDropdown.select(it.displaySubjectId)
b.teacherDropdown.select(it.displayTeacherId)
}
defaultLoaded = false
loadHours()
loadHours(it.displayStartTime)
})
return@setOnChangeListener false
}
@ -251,12 +314,11 @@ class EventManualV2Dialog(
.apply {
addOnPositiveButtonClickListener {
val dateSelected = Date.fromMillis(it)
b.dateDropdown.selected = TextInputDropDown.Item(
b.dateDropdown.select(TextInputDropDown.Item(
dateSelected.value.toLong(),
dateSelected.formattedString,
tag = dateSelected
)
b.dateDropdown.updateText()
))
loadHours()
}
show(this@EventManualV2Dialog.activity.supportFragmentManager, "MaterialDatePicker")
@ -276,7 +338,7 @@ class EventManualV2Dialog(
loadHours()
}}
private fun loadHours() {
private fun loadHours(defaultHour: Time? = null) {
b.timeDropdown.isEnabled = false
// get the selected date
val date = b.dateDropdown.selectedId?.let { Date.fromValue(it.toInt()) } ?: return
@ -338,6 +400,10 @@ class EventManualV2Dialog(
defaultLesson?.let {
b.timeDropdown.select(it.displayStartTime?.value?.toLong())
}
defaultHour?.let {
b.timeDropdown.select(it.value.toLong())
}
}
defaultLoaded = true
b.timeDropdown.isEnabled = true
@ -345,16 +411,16 @@ class EventManualV2Dialog(
// attach a listener to time dropdown
b.timeDropdown.setOnChangeListener { item ->
when {
// custom start hour
item.id == -1L -> {
return@setOnChangeListener false
}
// no lessons this day
item.id == -2L -> {
b.timeDropdown.deselect()
return@setOnChangeListener false
}
// custom start hour
item.id == -1L -> {
return@setOnChangeListener false
}
// selected a specific lesson
else -> {
if (item.tag is LessonFull) {

View File

@ -132,28 +132,28 @@ class LessonDetailsDialog(
if (lesson.type < Lesson.TYPE_SHIFTED_SOURCE && lesson.oldSubjectId != null && lesson.subjectId != lesson.oldSubjectId) {
b.oldSubjectName = lesson.oldSubjectName
}
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.subjectId != null) {
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.displaySubjectId != null) {
b.subjectName = lesson.subjectName
}
if (lesson.type < Lesson.TYPE_SHIFTED_SOURCE && lesson.oldTeacherId != null && lesson.teacherId != lesson.oldTeacherId) {
b.oldTeacherName = lesson.oldTeacherName
}
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.teacherId != null) {
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.displayTeacherId != null) {
b.teacherName = lesson.teacherName
}
if (lesson.oldClassroom != null && lesson.classroom != lesson.oldClassroom) {
b.oldClassroom = lesson.oldClassroom
}
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.classroom != null) {
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.displayClassroom != null) {
b.classroom = lesson.classroom
}
if (lesson.type < Lesson.TYPE_SHIFTED_SOURCE && lesson.oldTeamId != null && lesson.teamId != lesson.oldTeamId) {
b.oldTeamName = lesson.oldTeamName
}
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.teamId != null) {
if (lesson.type != Lesson.TYPE_CANCELLED && lesson.displayTeamId != null) {
b.teamName = lesson.teamName
}
}

View File

@ -75,21 +75,22 @@ class TextInputDropDown : TextInputEditText {
}
}
fun select(item: Item) {
fun select(item: Item): Item? {
selected = item
updateText()
return item
}
fun select(id: Long?) {
items.singleOrNull { it.id == id }?.let { select(it) }
fun select(id: Long?): Item? {
return items.singleOrNull { it.id == id }?.let { select(it) }
}
fun select(tag: Any?) {
items.singleOrNull { it.tag == tag }?.let { select(it) }
fun select(tag: Any?): Item? {
return items.singleOrNull { it.tag == tag }?.let { select(it) }
}
fun select(index: Int) {
items.getOrNull(index)?.let { select(it) }
fun select(index: Int): Item? {
return items.getOrNull(index)?.let { select(it) }
}
fun deselect(): TextInputDropDown {

View File

@ -4,11 +4,17 @@
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:padding="24dp">
@ -46,6 +52,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_team">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/teamDropdown"
android:layout_width="match_parent"
@ -54,33 +61,54 @@
tools:text="2b3T" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/shareSwitch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_event_manual_share_enabled" />
<TextView
android:id="@+id/shareDetails"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_event_manual_share_first_notice"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_subject">
android:baselineAligned="false"
android:orientation="horizontal">
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="@string/dialog_event_manual_type">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/subjectDropdown"
android:id="@+id/typeDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
tools:text="2b3T" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_teacher">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/teacherDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
tools:text="2b3T"/>
</com.google.android.material.textfield.TextInputLayout>
<FrameLayout
android:id="@+id/typeColor"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical"
android:layout_marginTop="2dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:background="@drawable/bg_circle"
android:foreground="?selectableItemBackgroundBorderless" />
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
@ -98,5 +126,64 @@
tools:text="2b3T" />
</com.google.android.material.textfield.TextInputLayout>
<com.mikepenz.iconics.view.IconicsCheckableTextView
android:id="@+id/showMore"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="16dp"
android:paddingBottom="16dp"
android:text="@string/dialog_event_manual_more_options"
android:background="?selectableItemBackground"
app:iiv_end_icon="cmd-chevron-down"
app:iiv_end_color="?android:textColorSecondary"
app:iiv_end_size="16dp"
app:iiv_end_checked_icon="cmd-chevron-up"
app:iiv_end_checked_color="?android:textColorSecondary"
app:iiv_end_checked_size="16dp"/>
<LinearLayout
android:id="@+id/moreLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_subject">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/subjectDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
tools:text="2b3T" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_teacher">
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
android:id="@+id/teacherDropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
tools:text="2b3T" />
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</layout>

View File

@ -21,10 +21,13 @@
<variable name="oldTeamName" type="String" />
<variable name="teamName" type="String" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="wrap_content"
android:padding="24dp">
<LinearLayout
@ -219,19 +222,6 @@
android:visibility="@{App.devMode ? View.VISIBLE : View.GONE}"
tools:text="12345" />
<!--<androidx.core.widget.NestedScrollView
android:id="@+id/gradeHistoryNest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="@{historyVisible ? View.VISIBLE : View.GONE}">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/gradeHistoryList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:listitem="@layout/row_grades_list_item" />
</androidx.core.widget.NestedScrollView>-->
</LinearLayout>
</ScrollView>
</layout>

View File

@ -1026,4 +1026,5 @@
<string name="snackbar_error_text">Wystąpił błąd</string>
<string name="dialog_sync_view_list_title">Synchronizacja ręczna</string>
<string name="timetable_no_subject_name">(brak nazwy)</string>
<string name="dialog_event_manual_more_options">Więcej opcji</string>
</resources>