From 3ca051983f54a033542b664f64a1b9b2b5f070bc Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Wed, 20 Nov 2019 22:15:43 +0100 Subject: [PATCH] [APIv2/Timetable] Add searching for the next lesson by team id --- .../data/db/modules/timetable/TimetableDao.kt | 8 + .../ui/dialogs/event/EventManualV2Dialog.kt | 531 +++++++++--------- 2 files changed, 280 insertions(+), 259 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt index 80812cb5..558d5766 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/modules/timetable/TimetableDao.kt @@ -60,6 +60,14 @@ interface TimetableDao { """) fun getNextWithSubject(profileId: Int, today: Date, subjectId: Long) : LiveData + @Query(""" + $QUERY + WHERE timetable.profileId = :profileId AND ((type != 3 AND date > :today) OR ((type = 3 OR type = 1) AND oldDate > :today)) AND timetable.subjectId = :subjectId AND timetable.teamId = :teamId + ORDER BY id, type + LIMIT 1 + """) + fun getNextWithSubjectAndTeam(profileId: Int, today: Date, subjectId: Long, teamId: Long): LiveData + @Query(""" $QUERY WHERE (type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt index e76036f5..955ef66b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/event/EventManualV2Dialog.kt @@ -57,286 +57,300 @@ class EventManualV2Dialog( private lateinit var event: Event private var customColor: Int? = null - init { run { - if (activity.isFinishing) - return@run - job = Job() - onShowListener?.invoke(TAG) - b = DialogEventManualV2Binding.inflate(activity.layoutInflater) - dialog = MaterialAlertDialogBuilder(activity) - .setTitle(R.string.dialog_event_manual_title) - .setView(b.root) - .setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } - .setPositiveButton(R.string.save) { _, _ -> saveEvent() } - .setOnDismissListener { - onDismissListener?.invoke(TAG) + init { + run { + if (activity.isFinishing) + return@run + job = Job() + onShowListener?.invoke(TAG) + b = DialogEventManualV2Binding.inflate(activity.layoutInflater) + dialog = MaterialAlertDialogBuilder(activity) + .setTitle(R.string.dialog_event_manual_title) + .setView(b.root) + .setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } + .setPositiveButton(R.string.save) { _, _ -> saveEvent() } + .setOnDismissListener { + onDismissListener?.invoke(TAG) + } + .show() + + event = editingEvent?.clone() ?: Event().also { event -> + event.profileId = profileId + /*defaultDate?.let { + event.eventDate = it + b.date = it } - .show() - - event = editingEvent?.clone() ?: Event().also { event -> - event.profileId = profileId - /*defaultDate?.let { - event.eventDate = it - b.date = it + defaultTime?.let { + event.startTime = it + b.time = it + } + defaultType?.let { + event.type = it + }*/ } - defaultTime?.let { - event.startTime = it - b.time = it + + 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) + } } - defaultType?.let { - event.type = it - }*/ + + loadLists() } + } - b.showMore.onClick { // TODO iconics is broken - it.apply { - refreshDrawableState() + private fun loadLists() { + launch { + val deferred = async(Dispatchers.Default) { + // get the team list + val teams = app.db.teamDao().getAllNow(profileId) + b.teamDropdown.clear() + b.teamDropdown += TextInputDropDown.Item( + -1, + activity.getString(R.string.dialog_event_manual_no_team), + "" + ) + b.teamDropdown += teams.map { TextInputDropDown.Item(it.id, it.name, tag = it) } - if (isChecked) - Anim.expand(b.moreLayout, 200, null) - else - Anim.collapse(b.moreLayout, 200, null) + // get the subject list + val subjects = app.db.subjectDao().getAllNow(profileId) + b.subjectDropdown.clear() + b.subjectDropdown += TextInputDropDown.Item( + -1, + activity.getString(R.string.dialog_event_manual_no_subject), + "" + ) + b.subjectDropdown += subjects.map { TextInputDropDown.Item(it.id, it.longName, tag = it) } + + // get the teacher list + val teachers = app.db.teacherDao().getAllNow(profileId) + b.teacherDropdown.clear() + b.teacherDropdown += TextInputDropDown.Item( + -1, + activity.getString(R.string.dialog_event_manual_no_teacher), + "" + ) + 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() - loadLists() - }} + b.teamDropdown.isEnabled = true + b.subjectDropdown.isEnabled = true + b.teacherDropdown.isEnabled = true + b.typeDropdown.isEnabled = true - private fun loadLists() { launch { - val deferred = async(Dispatchers.Default) { - // get the team list - val teams = app.db.teamDao().getAllNow(profileId) - b.teamDropdown.clear() - b.teamDropdown += TextInputDropDown.Item( - -1, - activity.getString(R.string.dialog_event_manual_no_team), - "" - ) - b.teamDropdown += teams.map { TextInputDropDown.Item(it.id, it.name, tag = it) } - - // get the subject list - val subjects = app.db.subjectDao().getAllNow(profileId) - b.subjectDropdown.clear() - b.subjectDropdown += TextInputDropDown.Item( - -1, - activity.getString(R.string.dialog_event_manual_no_subject), - "" - ) - b.subjectDropdown += subjects.map { TextInputDropDown.Item(it.id, it.longName, tag = it) } - - // get the teacher list - val teachers = app.db.teacherDao().getAllNow(profileId) - b.teacherDropdown.clear() - b.teacherDropdown += TextInputDropDown.Item( - -1, - activity.getString(R.string.dialog_event_manual_no_teacher), - "" - ) - 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 -> + b.typeDropdown.selected?.let { item -> customColor = (item.tag as EventType).color } - if (it.color != -1) - customColor = it.color - } - // copy IDs from the LessonFull - defaultLesson?.let { - b.teamDropdown.select(it.displayTeamId) - b.subjectDropdown.select(it.displaySubjectId) - b.teacherDropdown.select(it.displayTeacherId) - } + // 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 + } - 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") - } + // copy IDs from the LessonFull + defaultLesson?.let { + b.teamDropdown.select(it.displayTeamId) + b.subjectDropdown.select(it.displaySubjectId) + b.teacherDropdown.select(it.displayTeacherId) + } - loadDates() - }} + 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") + } - private fun loadDates() { launch { - val date = Date.getToday() - val today = date.value - var weekDay = date.weekDay + loadDates() + } + } - val deferred = async(Dispatchers.Default) { - val dates = mutableListOf() - // item choosing the next lesson of specific subject - b.subjectDropdown.selected?.let { - if (it.tag is Subject) { + private fun loadDates() { + launch { + val date = Date.getToday() + val today = date.value + var weekDay = date.weekDay + + val deferred = async(Dispatchers.Default) { + val dates = mutableListOf() + // item choosing the next lesson of specific subject + b.subjectDropdown.selected?.let { + if (it.tag is Subject) { + dates += TextInputDropDown.Item( + -it.id, + activity.getString(R.string.dialog_event_manual_date_next_lesson, it.tag.longName) + ) + } + } + + // TODAY + dates += TextInputDropDown.Item( + date.value.toLong(), + activity.getString(R.string.dialog_event_manual_date_today, date.formattedString), + tag = date.clone() + ) + + // TOMORROW + if (weekDay < 4) { + date.stepForward(0, 0, 1) + weekDay++ dates += TextInputDropDown.Item( - -it.id, - activity.getString(R.string.dialog_event_manual_date_next_lesson, it.tag.longName) + date.value.toLong(), + activity.getString(R.string.dialog_event_manual_date_tomorrow, date.formattedString), + tag = date.clone() ) } - } - - // TODAY - dates += TextInputDropDown.Item( - date.value.toLong(), - activity.getString(R.string.dialog_event_manual_date_today, date.formattedString), - tag = date.clone() - ) - - // TOMORROW - if (weekDay < 4) { - date.stepForward(0, 0, 1) - weekDay++ - dates += TextInputDropDown.Item( - date.value.toLong(), - activity.getString(R.string.dialog_event_manual_date_tomorrow, date.formattedString), - tag = date.clone() - ) - } - // REMAINING SCHOOL DAYS OF THE CURRENT WEEK - while (weekDay < 4) { - date.stepForward(0, 0, 1) // step one day forward - weekDay++ - dates += TextInputDropDown.Item( - date.value.toLong(), - activity.getString(R.string.dialog_event_manual_date_this_week, Week.getFullDayName(weekDay), date.formattedString), - tag = date.clone() - ) - } - // go to next week Monday - date.stepForward(0, 0, -weekDay + 7) - weekDay = 0 - // ALL SCHOOL DAYS OF THE NEXT WEEK - while (weekDay < 4) { - dates += TextInputDropDown.Item( - date.value.toLong(), - activity.getString(R.string.dialog_event_manual_date_next_week, Week.getFullDayName(weekDay), date.formattedString), - tag = date.clone() - ) - date.stepForward(0, 0, 1) // step one day forward - weekDay++ - } - dates += TextInputDropDown.Item( - -1L, - activity.getString(R.string.dialog_event_manual_date_other) - ) - dates - } - - val dates = deferred.await() - b.dateDropdown.clear().append(dates) - - editingEvent?.eventDate?.let { - b.dateDropdown.select(TextInputDropDown.Item( - it.value.toLong(), - it.formattedString, - tag = it - )) - } - - defaultLesson?.displayDate?.let { - b.dateDropdown.select(TextInputDropDown.Item( - it.value.toLong(), - it.formattedString, - tag = it - )) - } - - if (b.dateDropdown.selected == null) { - b.dateDropdown.select(today.toLong()) - } - - b.dateDropdown.isEnabled = true - - b.dateDropdown.setOnChangeListener { item -> - 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.select(TextInputDropDown.Item( - lessonDate.value.toLong(), - lessonDate.formattedString, - tag = lessonDate - )) - b.teamDropdown.select(it.displayTeamId) - b.subjectDropdown.select(it.displaySubjectId) - b.teacherDropdown.select(it.displayTeacherId) - defaultLoaded = false - loadHours(it.displayStartTime) - }) - return@setOnChangeListener false + // REMAINING SCHOOL DAYS OF THE CURRENT WEEK + while (weekDay < 4) { + date.stepForward(0, 0, 1) // step one day forward + weekDay++ + dates += TextInputDropDown.Item( + date.value.toLong(), + activity.getString(R.string.dialog_event_manual_date_this_week, Week.getFullDayName(weekDay), date.formattedString), + tag = date.clone() + ) } - // custom date - item.id == -1L -> { - MaterialDatePicker.Builder - .datePicker() - .setSelection((b.dateDropdown.selectedId?.let { Date.fromValue(it.toInt()) } ?: Date.getToday()).inMillis) - .build() - .apply { - addOnPositiveButtonClickListener { - val dateSelected = Date.fromMillis(it) - b.dateDropdown.select(TextInputDropDown.Item( - dateSelected.value.toLong(), - dateSelected.formattedString, - tag = dateSelected - )) - loadHours() + // go to next week Monday + date.stepForward(0, 0, -weekDay + 7) + weekDay = 0 + // ALL SCHOOL DAYS OF THE NEXT WEEK + while (weekDay < 4) { + dates += TextInputDropDown.Item( + date.value.toLong(), + activity.getString(R.string.dialog_event_manual_date_next_week, Week.getFullDayName(weekDay), date.formattedString), + tag = date.clone() + ) + date.stepForward(0, 0, 1) // step one day forward + weekDay++ + } + dates += TextInputDropDown.Item( + -1L, + activity.getString(R.string.dialog_event_manual_date_other) + ) + dates + } + + val dates = deferred.await() + b.dateDropdown.clear().append(dates) + + editingEvent?.eventDate?.let { + b.dateDropdown.select(TextInputDropDown.Item( + it.value.toLong(), + it.formattedString, + tag = it + )) + } + + defaultLesson?.displayDate?.let { + b.dateDropdown.select(TextInputDropDown.Item( + it.value.toLong(), + it.formattedString, + tag = it + )) + } + + if (b.dateDropdown.selected == null) { + b.dateDropdown.select(today.toLong()) + } + + b.dateDropdown.isEnabled = true + + b.dateDropdown.setOnChangeListener { item -> + when { + // next lesson with specified subject + item.id < -1 -> { + val teamId = defaultLesson?.teamId ?: -1 + val selectedLessonDate = defaultLesson?.date ?: Date.getToday() + + when (teamId) { + -1L -> app.db.timetableDao().getNextWithSubject(profileId, selectedLessonDate, -item.id) + else -> app.db.timetableDao().getNextWithSubjectAndTeam(profileId, selectedLessonDate, -item.id, teamId) + }.observeOnce(activity, Observer { + val lessonDate = it?.displayDate ?: return@Observer + b.dateDropdown.select(TextInputDropDown.Item( + lessonDate.value.toLong(), + lessonDate.formattedString, + tag = lessonDate + )) + b.teamDropdown.select(it.displayTeamId) + b.subjectDropdown.select(it.displaySubjectId) + b.teacherDropdown.select(it.displayTeacherId) + defaultLoaded = false + loadHours(it.displayStartTime) + }) + return@setOnChangeListener false + } + // custom date + item.id == -1L -> { + MaterialDatePicker.Builder + .datePicker() + .setSelection((b.dateDropdown.selectedId?.let { Date.fromValue(it.toInt()) } + ?: Date.getToday()).inMillis) + .build() + .apply { + addOnPositiveButtonClickListener { + val dateSelected = Date.fromMillis(it) + b.dateDropdown.select(TextInputDropDown.Item( + dateSelected.value.toLong(), + dateSelected.formattedString, + tag = dateSelected + )) + loadHours() + } + show(this@EventManualV2Dialog.activity.supportFragmentManager, "MaterialDatePicker") } - show(this@EventManualV2Dialog.activity.supportFragmentManager, "MaterialDatePicker") - } - return@setOnChangeListener false - } - // a specific date - else -> { - b.dateDropdown.select(item) - loadHours() + return@setOnChangeListener false + } + // a specific date + else -> { + b.dateDropdown.select(item) + loadHours() + } } + return@setOnChangeListener true } - return@setOnChangeListener true - } - loadHours() - }} + loadHours() + } + } private fun loadHours(defaultHour: Time? = null) { b.timeDropdown.isEnabled = false @@ -391,8 +405,7 @@ class EventManualV2Dialog( // clear subject, teacher selection b.subjectDropdown.deselect() b.teacherDropdown.deselect() - } - else { + } else { editingEvent?.let { b.timeDropdown.select(it.startTime?.value?.toLong()) } @@ -429,7 +442,7 @@ class EventManualV2Dialog( b.teamDropdown.deselect() b.subjectDropdown.deselect() b.teacherDropdown.deselect() - item.tag.displayTeamId?.let { + item.tag.displayTeamId?.let { b.teamDropdown.select(it) } item.tag.displaySubjectId?.let { @@ -449,4 +462,4 @@ class EventManualV2Dialog( private fun saveEvent() { } -} \ No newline at end of file +}