mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 13:48:20 +01:00
[Events/Manual] Create custom views for dropdowns. Simplify dialog code. Fix wrong start time saving.
This commit is contained in:
parent
70c307b796
commit
611ab0f100
@ -12,8 +12,6 @@ import androidx.appcompat.app.AlertDialog
|
|||||||
import androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL
|
import androidx.appcompat.app.AlertDialog.BUTTON_NEUTRAL
|
||||||
import androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE
|
import androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
import com.jaredrummler.android.colorpicker.ColorPickerDialog
|
||||||
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
|
||||||
@ -21,15 +19,17 @@ import kotlinx.coroutines.*
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
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
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class EventManualDialog(
|
class EventManualDialog(
|
||||||
@ -56,7 +56,6 @@ class EventManualDialog(
|
|||||||
private lateinit var b: DialogEventManualV2Binding
|
private lateinit var b: DialogEventManualV2Binding
|
||||||
private lateinit var dialog: AlertDialog
|
private lateinit var dialog: AlertDialog
|
||||||
|
|
||||||
private lateinit var event: Event
|
|
||||||
private var customColor: Int? = null
|
private var customColor: Int? = null
|
||||||
private val editingShared = editingEvent?.sharedBy != null
|
private val editingShared = editingEvent?.sharedBy != null
|
||||||
private val editingOwn = editingEvent?.sharedBy == "self"
|
private val editingOwn = editingEvent?.sharedBy == "self"
|
||||||
@ -104,12 +103,6 @@ class EventManualDialog(
|
|||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
|
|
||||||
event = editingEvent?.clone() ?: Event().also { event ->
|
|
||||||
event.profileId = profileId
|
|
||||||
defaultType?.let {
|
|
||||||
event.type = it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.shareSwitch.isChecked = editingShared
|
b.shareSwitch.isChecked = editingShared
|
||||||
b.shareSwitch.isEnabled = !editingShared || (editingShared && editingOwn)
|
b.shareSwitch.isEnabled = !editingShared || (editingShared && editingOwn)
|
||||||
|
|
||||||
@ -144,41 +137,85 @@ class EventManualDialog(
|
|||||||
else -> R.string.dialog_event_manual_share_first_notice
|
else -> R.string.dialog_event_manual_share_first_notice
|
||||||
}
|
}
|
||||||
|
|
||||||
b.shareDetails.setText(text, event.sharedByName ?: "")
|
b.shareDetails.setText(text, editingEvent?.sharedByName ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLists() { launch {
|
private fun loadLists() { launch {
|
||||||
|
with (b.dateDropdown) {
|
||||||
|
db = app.db
|
||||||
|
profileId = App.profileId
|
||||||
|
showWeekDays = false
|
||||||
|
showDays = true
|
||||||
|
showOtherDate = true
|
||||||
|
defaultLesson?.let {
|
||||||
|
nextLessonSubjectId = it.displaySubjectId
|
||||||
|
nextLessonSubjectName = it.displaySubjectName
|
||||||
|
nextLessonTeamId = it.displayTeamId
|
||||||
|
}
|
||||||
|
loadItems()
|
||||||
|
selectDefault(editingEvent?.eventDate)
|
||||||
|
selectDefault(defaultLesson?.displayDate ?: defaultDate)
|
||||||
|
onDateSelected = { date, lesson ->
|
||||||
|
b.timeDropdown.deselect()
|
||||||
|
b.timeDropdown.lessonsDate = date
|
||||||
|
this@EventManualDialog.launch {
|
||||||
|
b.timeDropdown.loadItems()
|
||||||
|
lesson?.displayStartTime?.let { b.timeDropdown.selectTime(it) }
|
||||||
|
lesson?.displaySubjectId?.let { b.subjectDropdown.selectSubject(it) } ?: b.subjectDropdown.deselect()
|
||||||
|
lesson?.displayTeacherId?.let { b.teacherDropdown.selectTeacher(it) } ?: b.teacherDropdown.deselect()
|
||||||
|
lesson?.displayTeamId?.let { b.teamDropdown.selectTeam(it) } ?: b.teamDropdown.selectTeamClass()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with (b.timeDropdown) {
|
||||||
|
db = app.db
|
||||||
|
profileId = App.profileId
|
||||||
|
showAllDay = true
|
||||||
|
showCustomTime = true
|
||||||
|
lessonsDate = b.dateDropdown.getSelected() as? Date ?: Date.getToday()
|
||||||
|
displayMode = DISPLAY_LESSONS
|
||||||
|
loadItems()
|
||||||
|
selectDefault(editingEvent?.startTime)
|
||||||
|
selectDefault(defaultLesson?.displayStartTime ?: defaultTime)
|
||||||
|
onLessonSelected = { lesson ->
|
||||||
|
lesson.displaySubjectId?.let { b.subjectDropdown.selectSubject(it) } ?: b.subjectDropdown.deselect()
|
||||||
|
lesson.displayTeacherId?.let { b.teacherDropdown.selectTeacher(it) } ?: b.teacherDropdown.deselect()
|
||||||
|
lesson.displayTeamId?.let { b.teamDropdown.selectTeam(it) } ?: b.teamDropdown.selectTeamClass()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with (b.teamDropdown) {
|
||||||
|
db = app.db
|
||||||
|
profileId = App.profileId
|
||||||
|
showNoTeam = true
|
||||||
|
loadItems()
|
||||||
|
selectTeamClass()
|
||||||
|
selectDefault(editingEvent?.teamId)
|
||||||
|
selectDefault(defaultLesson?.displayTeamId)
|
||||||
|
}
|
||||||
|
|
||||||
|
with (b.subjectDropdown) {
|
||||||
|
db = app.db
|
||||||
|
profileId = App.profileId
|
||||||
|
showNoSubject = true
|
||||||
|
showCustomSubject = false
|
||||||
|
loadItems()
|
||||||
|
selectDefault(editingEvent?.subjectId)
|
||||||
|
selectDefault(defaultLesson?.displaySubjectId)
|
||||||
|
}
|
||||||
|
|
||||||
|
with (b.teacherDropdown) {
|
||||||
|
db = app.db
|
||||||
|
profileId = App.profileId
|
||||||
|
showNoTeacher = true
|
||||||
|
loadItems()
|
||||||
|
selectDefault(editingEvent?.teacherId)
|
||||||
|
selectDefault(defaultLesson?.displayTeacherId)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val deferred = async(Dispatchers.Default) {
|
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
|
// get the event type list
|
||||||
val eventTypes = app.db.eventTypeDao().getAllNow(profileId)
|
val eventTypes = app.db.eventTypeDao().getAllNow(profileId)
|
||||||
b.typeDropdown.clear()
|
b.typeDropdown.clear()
|
||||||
@ -186,13 +223,10 @@ class EventManualDialog(
|
|||||||
}
|
}
|
||||||
deferred.await()
|
deferred.await()
|
||||||
|
|
||||||
b.teamDropdown.isEnabled = true
|
|
||||||
b.subjectDropdown.isEnabled = true
|
|
||||||
b.teacherDropdown.isEnabled = true
|
|
||||||
b.typeDropdown.isEnabled = true
|
b.typeDropdown.isEnabled = true
|
||||||
|
|
||||||
defaultType?.let {
|
defaultType?.let {
|
||||||
b.typeDropdown.select(it.toLong())
|
b.typeDropdown.select(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.typeDropdown.selected?.let { item ->
|
b.typeDropdown.selected?.let { item ->
|
||||||
@ -201,9 +235,6 @@ class EventManualDialog(
|
|||||||
|
|
||||||
// copy IDs from event being edited
|
// copy IDs from event being edited
|
||||||
editingEvent?.let {
|
editingEvent?.let {
|
||||||
b.teamDropdown.select(it.teamId)
|
|
||||||
b.subjectDropdown.select(it.subjectId)
|
|
||||||
b.teacherDropdown.select(it.teacherId)
|
|
||||||
b.topic.setText(it.topic)
|
b.topic.setText(it.topic)
|
||||||
b.typeDropdown.select(it.type.toLong())?.let { item ->
|
b.typeDropdown.select(it.type.toLong())?.let { item ->
|
||||||
customColor = (item.tag as EventType).color
|
customColor = (item.tag as EventType).color
|
||||||
@ -215,8 +246,6 @@ class EventManualDialog(
|
|||||||
// copy IDs from the LessonFull
|
// copy IDs from the LessonFull
|
||||||
defaultLesson?.let {
|
defaultLesson?.let {
|
||||||
b.teamDropdown.select(it.displayTeamId)
|
b.teamDropdown.select(it.displayTeamId)
|
||||||
b.subjectDropdown.select(it.displaySubjectId)
|
|
||||||
b.teacherDropdown.select(it.displayTeacherId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b.typeDropdown.setOnChangeListener {
|
b.typeDropdown.setOnChangeListener {
|
||||||
@ -244,278 +273,8 @@ class EventManualDialog(
|
|||||||
})
|
})
|
||||||
colorPickerDialog.show(activity.fragmentManager, "color-picker-dialog")
|
colorPickerDialog.show(activity.fragmentManager, "color-picker-dialog")
|
||||||
}
|
}
|
||||||
|
|
||||||
loadDates()
|
|
||||||
}}
|
}}
|
||||||
|
|
||||||
private fun loadDates() { launch {
|
|
||||||
val date = Date.getToday()
|
|
||||||
val today = date.value
|
|
||||||
var weekDay = date.weekDay
|
|
||||||
|
|
||||||
val deferred = async(Dispatchers.Default) {
|
|
||||||
val dates = mutableListOf<TextInputDropDown.Item>()
|
|
||||||
// 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(
|
|
||||||
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)
|
|
||||||
|
|
||||||
defaultDate?.let {
|
|
||||||
event.eventDate = it
|
|
||||||
if (b.dateDropdown.select(it) == null)
|
|
||||||
b.dateDropdown.select(TextInputDropDown.Item(
|
|
||||||
it.value.toLong(),
|
|
||||||
it.formattedString,
|
|
||||||
tag = it
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
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@EventManualDialog.activity.supportFragmentManager, "MaterialDatePicker")
|
|
||||||
}
|
|
||||||
|
|
||||||
return@setOnChangeListener false
|
|
||||||
}
|
|
||||||
// a specific date
|
|
||||||
else -> {
|
|
||||||
b.dateDropdown.select(item)
|
|
||||||
loadHours()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return@setOnChangeListener true
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
// get all lessons for selected date
|
|
||||||
app.db.timetableDao().getForDate(profileId, date).observeOnce(activity, Observer { lessons ->
|
|
||||||
val hours = mutableListOf<TextInputDropDown.Item>()
|
|
||||||
// add All day time choice
|
|
||||||
hours += TextInputDropDown.Item(
|
|
||||||
0L,
|
|
||||||
activity.getString(R.string.dialog_event_manual_all_day)
|
|
||||||
)
|
|
||||||
lessons.forEach { lesson ->
|
|
||||||
if (lesson.type == Lesson.TYPE_NO_LESSONS) {
|
|
||||||
// indicate there are no lessons this day
|
|
||||||
hours += TextInputDropDown.Item(
|
|
||||||
-2L,
|
|
||||||
activity.getString(R.string.dialog_event_manual_no_lessons)
|
|
||||||
)
|
|
||||||
return@forEach
|
|
||||||
}
|
|
||||||
// create the lesson caption
|
|
||||||
val text = listOfNotEmpty(
|
|
||||||
lesson.displayStartTime?.stringHM ?: "",
|
|
||||||
lesson.displaySubjectName?.let {
|
|
||||||
when {
|
|
||||||
lesson.type == Lesson.TYPE_CANCELLED
|
|
||||||
|| lesson.type == Lesson.TYPE_SHIFTED_SOURCE -> it.asStrikethroughSpannable()
|
|
||||||
lesson.type != Lesson.TYPE_NORMAL -> it.asItalicSpannable()
|
|
||||||
else -> it
|
|
||||||
}
|
|
||||||
} ?: ""
|
|
||||||
)
|
|
||||||
// add an item with LessonFull as the tag
|
|
||||||
hours += TextInputDropDown.Item(
|
|
||||||
lesson.displayStartTime?.value?.toLong() ?: -1,
|
|
||||||
text.concat(" "),
|
|
||||||
tag = lesson
|
|
||||||
)
|
|
||||||
}
|
|
||||||
b.timeDropdown.clear().append(hours)
|
|
||||||
|
|
||||||
if (defaultLoaded) {
|
|
||||||
b.timeDropdown.deselect()
|
|
||||||
// select the TEAM_CLASS if possible
|
|
||||||
b.teamDropdown.items.singleOrNull {
|
|
||||||
it.tag is Team && it.tag.type == Team.TYPE_CLASS
|
|
||||||
}?.let {
|
|
||||||
b.teamDropdown.select(it)
|
|
||||||
} ?: b.teamDropdown.deselect()
|
|
||||||
|
|
||||||
// clear subject, teacher selection
|
|
||||||
b.subjectDropdown.deselect()
|
|
||||||
b.teacherDropdown.deselect()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val setTime: (Time) -> Unit = {
|
|
||||||
event.startTime = it
|
|
||||||
if (b.timeDropdown.select(it) == null)
|
|
||||||
b.timeDropdown.select(TextInputDropDown.Item(
|
|
||||||
it.value.toLong(),
|
|
||||||
it.stringHM,
|
|
||||||
tag = it
|
|
||||||
))
|
|
||||||
}
|
|
||||||
defaultTime?.let(setTime)
|
|
||||||
editingEvent?.startTime?.let(setTime)
|
|
||||||
defaultLesson?.displayStartTime?.let(setTime)
|
|
||||||
defaultHour?.let(setTime)
|
|
||||||
}
|
|
||||||
defaultLoaded = true
|
|
||||||
b.timeDropdown.isEnabled = true
|
|
||||||
|
|
||||||
// attach a listener to time dropdown
|
|
||||||
b.timeDropdown.setOnChangeListener { item ->
|
|
||||||
when (item.id) {
|
|
||||||
// no lessons this day
|
|
||||||
-2L -> {
|
|
||||||
b.timeDropdown.deselect()
|
|
||||||
return@setOnChangeListener false
|
|
||||||
}
|
|
||||||
|
|
||||||
// custom start hour
|
|
||||||
-1L -> return@setOnChangeListener false
|
|
||||||
|
|
||||||
// selected a specific lesson
|
|
||||||
else -> {
|
|
||||||
if (item.tag is LessonFull) {
|
|
||||||
// update team, subject, teacher dropdowns,
|
|
||||||
// using the LessonFull from item tag
|
|
||||||
b.teamDropdown.deselect()
|
|
||||||
b.subjectDropdown.deselect()
|
|
||||||
b.teacherDropdown.deselect()
|
|
||||||
item.tag.displayTeamId?.let {
|
|
||||||
b.teamDropdown.select(it)
|
|
||||||
}
|
|
||||||
item.tag.displaySubjectId?.let {
|
|
||||||
b.subjectDropdown.select(it)
|
|
||||||
}
|
|
||||||
item.tag.displayTeacherId?.let {
|
|
||||||
b.teacherDropdown.select(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return@setOnChangeListener true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showRemoveEventDialog() {
|
private fun showRemoveEventDialog() {
|
||||||
val shareNotice = when {
|
val shareNotice = when {
|
||||||
editingShared && editingOwn -> "\n\n"+activity.getString(R.string.dialog_event_manual_remove_shared_self)
|
editingShared && editingOwn -> "\n\n"+activity.getString(R.string.dialog_event_manual_remove_shared_self)
|
||||||
@ -541,22 +300,29 @@ class EventManualDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun saveEvent() {
|
private fun saveEvent() {
|
||||||
val date = b.dateDropdown.selected?.tag.instanceOfOrNull<Date>()
|
val date = b.dateDropdown.getSelected() as? Date
|
||||||
val startTime = b.timeDropdown.selected?.tag.instanceOfOrNull<Time>()
|
val startTimePair = b.timeDropdown.getSelected() as? Pair<*, *>
|
||||||
val teamId = b.teamDropdown.selected?.id
|
val startTime = startTimePair?.first as? Time
|
||||||
|
val teamId = b.teamDropdown.getSelected() as? Long
|
||||||
val type = b.typeDropdown.selected?.id
|
val type = b.typeDropdown.selected?.id
|
||||||
val topic = b.topic.text?.toString()
|
val topic = b.topic.text?.toString()
|
||||||
val subjectId = b.subjectDropdown.selected?.id
|
val subjectId = b.subjectDropdown.getSelected() as? Long
|
||||||
val teacherId = b.teacherDropdown.selected?.id
|
val teacherId = b.teacherDropdown.getSelected() as? Long
|
||||||
|
|
||||||
val share = b.shareSwitch.isChecked
|
val share = b.shareSwitch.isChecked
|
||||||
|
|
||||||
|
b.dateDropdown.error = null
|
||||||
b.teamDropdown.error = null
|
b.teamDropdown.error = null
|
||||||
b.typeDropdown.error = null
|
b.typeDropdown.error = null
|
||||||
b.topic.error = null
|
b.topic.error = null
|
||||||
|
|
||||||
var isError = false
|
var isError = false
|
||||||
|
|
||||||
|
if (date == null) {
|
||||||
|
b.dateDropdown.error = app.getString(R.string.dialog_event_manual_date_choose)
|
||||||
|
isError = true
|
||||||
|
}
|
||||||
|
|
||||||
if (share && teamId == null) {
|
if (share && teamId == null) {
|
||||||
b.teamDropdown.error = app.getString(R.string.dialog_event_manual_team_choose)
|
b.teamDropdown.error = app.getString(R.string.dialog_event_manual_team_choose)
|
||||||
isError = true
|
isError = true
|
||||||
|
@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.ContextWrapper
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.lifecycle.Observer
|
||||||
|
import com.google.android.material.datepicker.MaterialDatePicker
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
||||||
|
import pl.szczodrzynski.edziennik.observeOnce
|
||||||
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
|
class DateDropdown : TextInputDropDown {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
|
private val activity: AppCompatActivity?
|
||||||
|
get() {
|
||||||
|
var context: Context? = context ?: return null
|
||||||
|
if (context is AppCompatActivity) return context
|
||||||
|
while (context is ContextWrapper) {
|
||||||
|
if (context is AppCompatActivity)
|
||||||
|
return context
|
||||||
|
context = context.baseContext
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDb
|
||||||
|
var profileId: Int = 0
|
||||||
|
var showWeekDays = false
|
||||||
|
var showDays = true
|
||||||
|
var showOtherDate = true
|
||||||
|
var nextLessonSubjectId: Long? = null
|
||||||
|
var nextLessonSubjectName: String? = null
|
||||||
|
var nextLessonTeamId: Long? = null
|
||||||
|
var onDateSelected: ((date: Date, lesson: LessonFull?) -> Unit)? = null
|
||||||
|
var onWeekDaySelected: ((weekDay: Int) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun create(context: Context) {
|
||||||
|
super.create(context)
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadItems() {
|
||||||
|
val date = Date.getToday()
|
||||||
|
val today = date.value
|
||||||
|
var weekDay = date.weekDay
|
||||||
|
|
||||||
|
val dates = withContext(Dispatchers.Default) {
|
||||||
|
val dates = mutableListOf<Item>()
|
||||||
|
|
||||||
|
nextLessonSubjectId?.let {
|
||||||
|
// item choosing the next lesson of specific subject - relative to selected date
|
||||||
|
dates += Item(
|
||||||
|
-it,
|
||||||
|
context.getString(R.string.dialog_event_manual_date_next_lesson, nextLessonSubjectName),
|
||||||
|
tag = nextLessonSubjectName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showWeekDays) {
|
||||||
|
for (i in Week.MONDAY..Week.SUNDAY) {
|
||||||
|
dates += Item(
|
||||||
|
i.toLong(),
|
||||||
|
Week.getFullDayName(i),
|
||||||
|
tag = i
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showDays) {
|
||||||
|
// TODAY
|
||||||
|
dates += Item(
|
||||||
|
date.value.toLong(),
|
||||||
|
context.getString(R.string.dialog_event_manual_date_today, date.formattedString),
|
||||||
|
tag = date.clone()
|
||||||
|
)
|
||||||
|
|
||||||
|
// TOMORROW
|
||||||
|
if (weekDay < 4) {
|
||||||
|
date.stepForward(0, 0, 1)
|
||||||
|
weekDay++
|
||||||
|
dates += Item(
|
||||||
|
date.value.toLong(),
|
||||||
|
context.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 += Item(
|
||||||
|
date.value.toLong(),
|
||||||
|
context.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 += Item(
|
||||||
|
date.value.toLong(),
|
||||||
|
context.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++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showOtherDate) {
|
||||||
|
dates += Item(
|
||||||
|
-1L,
|
||||||
|
context.getString(R.string.dialog_event_manual_date_other),
|
||||||
|
tag = -1L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
dates
|
||||||
|
}
|
||||||
|
|
||||||
|
clear().append(dates)
|
||||||
|
isEnabled = true
|
||||||
|
|
||||||
|
setOnChangeListener { item ->
|
||||||
|
when (item.tag) {
|
||||||
|
-1L -> {
|
||||||
|
pickerDialog()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
is Date -> {
|
||||||
|
onDateSelected?.invoke(item.tag, null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is Int -> {
|
||||||
|
onWeekDaySelected?.invoke(item.tag)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is String -> {
|
||||||
|
/* next lesson of subject */
|
||||||
|
activity ?: return@setOnChangeListener false
|
||||||
|
val subjectId = -item.id
|
||||||
|
val startDate = getSelected() as? Date ?: Date.getToday()
|
||||||
|
when (nextLessonTeamId) {
|
||||||
|
null -> db.timetableDao().getNextWithSubject(profileId, startDate, subjectId)
|
||||||
|
else -> db.timetableDao().getNextWithSubjectAndTeam(profileId, startDate, subjectId, nextLessonTeamId ?: -1)
|
||||||
|
}.observeOnce(activity!!, Observer {
|
||||||
|
if (it == null) {
|
||||||
|
Toast.makeText(context, R.string.dropdown_date_no_more_lessons, Toast.LENGTH_LONG).show()
|
||||||
|
return@Observer
|
||||||
|
}
|
||||||
|
val lessonDate = it.displayDate ?: return@Observer
|
||||||
|
selectDate(lessonDate)
|
||||||
|
onDateSelected?.invoke(lessonDate, it)
|
||||||
|
})
|
||||||
|
false
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pickerDialog() {
|
||||||
|
MaterialDatePicker.Builder
|
||||||
|
.datePicker()
|
||||||
|
.setSelection(
|
||||||
|
if (selected?.tag is Date)
|
||||||
|
(selected?.tag as Date).inMillis
|
||||||
|
else
|
||||||
|
Date.getToday().inMillis
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
.apply {
|
||||||
|
addOnPositiveButtonClickListener {
|
||||||
|
val dateSelected = Date.fromMillis(it)
|
||||||
|
selectDate(dateSelected)
|
||||||
|
}
|
||||||
|
this@DateDropdown.activity ?: return@apply
|
||||||
|
show(this@DateDropdown.activity!!.supportFragmentManager, "MaterialDatePicker")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDate(date: Date) {
|
||||||
|
if (select(date) == null)
|
||||||
|
select(Item(
|
||||||
|
date.value.toLong(),
|
||||||
|
date.formattedString,
|
||||||
|
tag = date
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fun selectWeekDay(weekDay: Int) {
|
||||||
|
if (select(tag = weekDay) == null)
|
||||||
|
select(Item(
|
||||||
|
weekDay.toLong(),
|
||||||
|
Week.getFullDayName(weekDay),
|
||||||
|
tag = weekDay
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDefault(date: Date?) {
|
||||||
|
if (date == null || selected != null)
|
||||||
|
return
|
||||||
|
selectDate(date)
|
||||||
|
}
|
||||||
|
fun selectDefault(weekDay: Int?) {
|
||||||
|
if (weekDay == null || selected != null)
|
||||||
|
return
|
||||||
|
selectWeekDay(weekDay)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected date.
|
||||||
|
* ### Returns:
|
||||||
|
* - null if no valid date is selected
|
||||||
|
* - [Date] - the selected date, if [showDays] or [showOtherDate] == true
|
||||||
|
* - [Int] - the selected week day, if [showWeekDays] == true
|
||||||
|
*/
|
||||||
|
fun getSelected(): Any? {
|
||||||
|
return when (val tag = selected?.tag) {
|
||||||
|
is Date -> tag
|
||||||
|
is Int -> tag
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.ContextWrapper
|
||||||
|
import android.text.InputType
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
|
|
||||||
|
class SubjectDropdown : TextInputDropDown {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
|
private val activity: AppCompatActivity?
|
||||||
|
get() {
|
||||||
|
var context: Context? = context ?: return null
|
||||||
|
if (context is AppCompatActivity) return context
|
||||||
|
while (context is ContextWrapper) {
|
||||||
|
if (context is AppCompatActivity)
|
||||||
|
return context
|
||||||
|
context = context.baseContext
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDb
|
||||||
|
var profileId: Int = 0
|
||||||
|
var showNoSubject = true
|
||||||
|
var showCustomSubject = false
|
||||||
|
var customSubjectName = ""
|
||||||
|
var onSubjectSelected: ((subjectId: Long?) -> Unit)? = null
|
||||||
|
var onCustomSubjectSelected: ((subjectName: String) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun create(context: Context) {
|
||||||
|
super.create(context)
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadItems() {
|
||||||
|
val subjects = withContext(Dispatchers.Default) {
|
||||||
|
val list = mutableListOf<Item>()
|
||||||
|
|
||||||
|
if (showNoSubject) {
|
||||||
|
list += Item(
|
||||||
|
-1L,
|
||||||
|
context.getString(R.string.dialog_event_manual_no_subject),
|
||||||
|
tag = -1L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showCustomSubject) {
|
||||||
|
list += Item(
|
||||||
|
-2L,
|
||||||
|
context.getString(R.string.dropdown_subject_custom),
|
||||||
|
tag = -2L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val subjects = db.subjectDao().getAllNow(profileId)
|
||||||
|
|
||||||
|
list += subjects.map { Item(
|
||||||
|
it.id,
|
||||||
|
it.longName,
|
||||||
|
tag = it.id
|
||||||
|
) }
|
||||||
|
|
||||||
|
list
|
||||||
|
}
|
||||||
|
|
||||||
|
clear().append(subjects)
|
||||||
|
isEnabled = true
|
||||||
|
|
||||||
|
setOnChangeListener {
|
||||||
|
when (it.tag) {
|
||||||
|
-2L -> {
|
||||||
|
// custom subject
|
||||||
|
customNameDialog()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
-1L -> {
|
||||||
|
// no subject
|
||||||
|
onSubjectSelected?.invoke(null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is Long -> {
|
||||||
|
// selected a subject
|
||||||
|
onSubjectSelected?.invoke(it.tag)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun customNameDialog() {
|
||||||
|
activity ?: return
|
||||||
|
MaterialDialog.Builder(activity!!)
|
||||||
|
.title("Własny przedmiot")
|
||||||
|
.inputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE)
|
||||||
|
.input("Nazwa", "") { _: MaterialDialog?, input: CharSequence ->
|
||||||
|
customSubjectName = input.toString()
|
||||||
|
select(Item(
|
||||||
|
-1L * customSubjectName.crc16(),
|
||||||
|
customSubjectName,
|
||||||
|
tag = customSubjectName
|
||||||
|
))
|
||||||
|
onCustomSubjectSelected?.invoke(customSubjectName)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectSubject(subjectId: Long) {
|
||||||
|
if (select(subjectId) == null)
|
||||||
|
select(Item(
|
||||||
|
subjectId,
|
||||||
|
"nieznany przedmiot ($subjectId)",
|
||||||
|
tag = subjectId
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDefault(subjectId: Long?) {
|
||||||
|
if (subjectId == null || selected != null)
|
||||||
|
return
|
||||||
|
selectSubject(subjectId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected subject.
|
||||||
|
* ### Returns:
|
||||||
|
* - null if no valid subject is selected
|
||||||
|
* - [Long] - the selected subject's ID
|
||||||
|
* - [String] - a custom subject name entered, if [showCustomSubject] == true
|
||||||
|
*/
|
||||||
|
fun getSelected(): Any? {
|
||||||
|
return when (selected?.tag) {
|
||||||
|
-1L -> null
|
||||||
|
is Long -> selected?.tag as Long
|
||||||
|
is String -> selected?.tag as String
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.ContextWrapper
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
|
|
||||||
|
class TeacherDropdown : TextInputDropDown {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
|
private val activity: AppCompatActivity?
|
||||||
|
get() {
|
||||||
|
var context: Context? = context ?: return null
|
||||||
|
if (context is AppCompatActivity) return context
|
||||||
|
while (context is ContextWrapper) {
|
||||||
|
if (context is AppCompatActivity)
|
||||||
|
return context
|
||||||
|
context = context.baseContext
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDb
|
||||||
|
var profileId: Int = 0
|
||||||
|
var showNoTeacher = true
|
||||||
|
var onTeacherSelected: ((teacherId: Long?) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun create(context: Context) {
|
||||||
|
super.create(context)
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadItems() {
|
||||||
|
val teachers = withContext(Dispatchers.Default) {
|
||||||
|
val list = mutableListOf<Item>()
|
||||||
|
|
||||||
|
if (showNoTeacher) {
|
||||||
|
list += Item(
|
||||||
|
-1L,
|
||||||
|
context.getString(R.string.dialog_event_manual_no_teacher),
|
||||||
|
tag = -1L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val teachers = db.teacherDao().getAllNow(profileId)
|
||||||
|
|
||||||
|
list += teachers.map { Item(
|
||||||
|
it.id,
|
||||||
|
it.fullName,
|
||||||
|
tag = it.id
|
||||||
|
) }
|
||||||
|
|
||||||
|
list
|
||||||
|
}
|
||||||
|
|
||||||
|
clear().append(teachers)
|
||||||
|
isEnabled = true
|
||||||
|
|
||||||
|
setOnChangeListener {
|
||||||
|
when (it.tag) {
|
||||||
|
-1L -> {
|
||||||
|
// no teacher
|
||||||
|
onTeacherSelected?.invoke(null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is Long -> {
|
||||||
|
// selected a teacher
|
||||||
|
onTeacherSelected?.invoke(it.tag)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectTeacher(teacherId: Long) {
|
||||||
|
if (select(teacherId) == null)
|
||||||
|
select(Item(
|
||||||
|
teacherId,
|
||||||
|
"nieznany nauczyciel ($teacherId)",
|
||||||
|
tag = teacherId
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDefault(teacherId: Long?) {
|
||||||
|
if (teacherId == null || selected != null)
|
||||||
|
return
|
||||||
|
selectTeacher(teacherId)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected teacher.
|
||||||
|
* ### Returns:
|
||||||
|
* - null if no valid teacher is selected
|
||||||
|
* - [Long] - the selected teacher's ID
|
||||||
|
*/
|
||||||
|
fun getSelected(): Long? {
|
||||||
|
return when (selected?.tag) {
|
||||||
|
-1L -> null
|
||||||
|
is Long -> selected?.tag as Long
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-3-7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.ContextWrapper
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
||||||
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
|
|
||||||
|
class TeamDropdown : TextInputDropDown {
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
|
private val activity: AppCompatActivity?
|
||||||
|
get() {
|
||||||
|
var context: Context? = context ?: return null
|
||||||
|
if (context is AppCompatActivity) return context
|
||||||
|
while (context is ContextWrapper) {
|
||||||
|
if (context is AppCompatActivity)
|
||||||
|
return context
|
||||||
|
context = context.baseContext
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDb
|
||||||
|
var profileId: Int = 0
|
||||||
|
var showNoTeam = true
|
||||||
|
var onTeamSelected: ((teamId: Long?) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun create(context: Context) {
|
||||||
|
super.create(context)
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadItems() {
|
||||||
|
val teams = withContext(Dispatchers.Default) {
|
||||||
|
val list = mutableListOf<Item>()
|
||||||
|
|
||||||
|
if (showNoTeam) {
|
||||||
|
list += Item(
|
||||||
|
-1L,
|
||||||
|
context.getString(R.string.dialog_event_manual_no_team),
|
||||||
|
tag = -1L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val teams = db.teamDao().getAllNow(profileId)
|
||||||
|
|
||||||
|
list += teams.map { Item(
|
||||||
|
it.id,
|
||||||
|
it.name,
|
||||||
|
tag = it.id
|
||||||
|
) }
|
||||||
|
|
||||||
|
list
|
||||||
|
}
|
||||||
|
|
||||||
|
clear().append(teams)
|
||||||
|
isEnabled = true
|
||||||
|
|
||||||
|
setOnChangeListener {
|
||||||
|
when (it.tag) {
|
||||||
|
-1L -> {
|
||||||
|
// no team
|
||||||
|
onTeamSelected?.invoke(null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is Long -> {
|
||||||
|
// selected a team
|
||||||
|
onTeamSelected?.invoke(it.tag)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectTeam(teamId: Long) {
|
||||||
|
if (select(teamId) == null)
|
||||||
|
select(Item(
|
||||||
|
teamId,
|
||||||
|
"nieznana grupa ($teamId)",
|
||||||
|
tag = teamId
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDefault(teamId: Long?) {
|
||||||
|
if (teamId == null || selected != null)
|
||||||
|
return
|
||||||
|
selectTeam(teamId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectTeamClass() {
|
||||||
|
select(items.singleOrNull {
|
||||||
|
it.tag is Team && it.tag.type == Team.TYPE_CLASS
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected team.
|
||||||
|
* ### Returns:
|
||||||
|
* - null if no valid team is selected
|
||||||
|
* - [Long] - the team's ID
|
||||||
|
*/
|
||||||
|
fun getSelected(): Any? {
|
||||||
|
return when (selected?.tag) {
|
||||||
|
-1L -> null
|
||||||
|
is Long -> selected?.tag as Long
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.modules.views
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.ContextWrapper
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
||||||
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
|
class TimeDropdown : TextInputDropDown {
|
||||||
|
companion object {
|
||||||
|
const val DISPLAY_LESSON_RANGES = 0
|
||||||
|
const val DISPLAY_LESSONS = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context) : super(context)
|
||||||
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||||
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||||
|
|
||||||
|
private val activity: AppCompatActivity?
|
||||||
|
get() {
|
||||||
|
var context: Context? = context ?: return null
|
||||||
|
if (context is AppCompatActivity) return context
|
||||||
|
while (context is ContextWrapper) {
|
||||||
|
if (context is AppCompatActivity)
|
||||||
|
return context
|
||||||
|
context = context.baseContext
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
lateinit var db: AppDb
|
||||||
|
var profileId: Int = 0
|
||||||
|
var showAllDay = false
|
||||||
|
var showCustomTime = true
|
||||||
|
var displayMode = DISPLAY_LESSON_RANGES
|
||||||
|
var lessonsDate: Date? = null
|
||||||
|
var onTimeSelected: ((startTime: Time?, endTime: Time?, lessonNumber: Int?) -> Unit)? = null
|
||||||
|
var onLessonSelected: ((lesson: LessonFull) -> Unit)? = null
|
||||||
|
|
||||||
|
override fun create(context: Context) {
|
||||||
|
super.create(context)
|
||||||
|
isEnabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun loadItems() {
|
||||||
|
val hours = withContext(Dispatchers.Default) {
|
||||||
|
val hours = mutableListOf<Item>()
|
||||||
|
|
||||||
|
if (showAllDay) {
|
||||||
|
hours += Item(
|
||||||
|
0L,
|
||||||
|
context.getString(R.string.dialog_event_manual_all_day),
|
||||||
|
tag = 0L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showCustomTime) {
|
||||||
|
hours += Item(
|
||||||
|
-1,
|
||||||
|
context.getString(R.string.dialog_event_manual_custom_time),
|
||||||
|
tag = -1L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayMode == DISPLAY_LESSON_RANGES) {
|
||||||
|
val lessonRanges = db.lessonRangeDao().getAllNow(profileId)
|
||||||
|
|
||||||
|
hours += lessonRanges.map { Item(
|
||||||
|
it.startTime.value.toLong(),
|
||||||
|
context.getString(R.string.timetable_manual_dialog_time_format, it.startTime.stringHM, it.lessonNumber),
|
||||||
|
tag = it
|
||||||
|
) }
|
||||||
|
}
|
||||||
|
else if (displayMode == DISPLAY_LESSONS && lessonsDate != null) {
|
||||||
|
val lessons = db.timetableDao().getForDateNow(profileId, lessonsDate!!)
|
||||||
|
|
||||||
|
hours += lessons.map { lesson ->
|
||||||
|
if (lesson.type == Lesson.TYPE_NO_LESSONS) {
|
||||||
|
// indicate there are no lessons this day
|
||||||
|
return@map Item(
|
||||||
|
-2L,
|
||||||
|
context.getString(R.string.dialog_event_manual_no_lessons),
|
||||||
|
tag = -2L
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// create the lesson caption
|
||||||
|
val text = listOfNotEmpty(
|
||||||
|
lesson.displayStartTime?.stringHM ?: "",
|
||||||
|
if (lesson.displaySubjectName != null) "-" else "",
|
||||||
|
lesson.displaySubjectName?.let {
|
||||||
|
when {
|
||||||
|
lesson.type == Lesson.TYPE_CANCELLED
|
||||||
|
|| lesson.type == Lesson.TYPE_SHIFTED_SOURCE -> it.asStrikethroughSpannable()
|
||||||
|
lesson.type != Lesson.TYPE_NORMAL -> it.asItalicSpannable()
|
||||||
|
else -> it
|
||||||
|
}
|
||||||
|
} ?: ""
|
||||||
|
)
|
||||||
|
// add an item with LessonFull as the tag
|
||||||
|
return@map Item(
|
||||||
|
lesson.displayStartTime?.value?.toLong() ?: -1,
|
||||||
|
text.concat(" "),
|
||||||
|
tag = lesson
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hours
|
||||||
|
}
|
||||||
|
|
||||||
|
clear().append(hours)
|
||||||
|
isEnabled = true
|
||||||
|
|
||||||
|
setOnChangeListener {
|
||||||
|
when (it.tag) {
|
||||||
|
-2L -> {
|
||||||
|
// no lessons this day
|
||||||
|
deselect()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
-1L -> {
|
||||||
|
// custom start hour
|
||||||
|
pickerDialog()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
0L -> {
|
||||||
|
// selected all day
|
||||||
|
onTimeSelected?.invoke(null, null, null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is LessonFull -> {
|
||||||
|
// selected a specific lesson
|
||||||
|
onLessonSelected?.invoke(it.tag)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is LessonRange -> {
|
||||||
|
// selected a lesson range
|
||||||
|
onTimeSelected?.invoke(it.tag.startTime, it.tag.endTime, it.tag.lessonNumber)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
is Time -> {
|
||||||
|
// selected a time
|
||||||
|
onTimeSelected?.invoke(it.tag, null, null)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun pickerDialog() {
|
||||||
|
/*MaterialDatePicker.Builder
|
||||||
|
.datePicker()
|
||||||
|
.setSelection((selectedId?.let { Date.fromValue(it.toInt()) }
|
||||||
|
?: Date.getToday()).inMillis)
|
||||||
|
.build()
|
||||||
|
.apply {
|
||||||
|
addOnPositiveButtonClickListener {
|
||||||
|
val dateSelected = Date.fromMillis(it)
|
||||||
|
selectDate(dateSelected)
|
||||||
|
}
|
||||||
|
this@DateDropdown.activity ?: return@apply
|
||||||
|
show(this@DateDropdown.activity!!.supportFragmentManager, "MaterialDatePicker")
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectTime(time: Time) {
|
||||||
|
if (select(time.value.toLong()) == null)
|
||||||
|
select(Item(
|
||||||
|
time.value.toLong(),
|
||||||
|
time.stringHM,
|
||||||
|
tag = time
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun selectDefault(time: Time?) {
|
||||||
|
if (time == null || selected != null)
|
||||||
|
return
|
||||||
|
selectTime(time)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the currently selected time.
|
||||||
|
* ### Returns:
|
||||||
|
* - null if no valid time is selected
|
||||||
|
* - a [Pair] of [Time] and [Time]? - the selected time object, if [displayMode] == [DISPLAY_LESSONS] or [showCustomTime]
|
||||||
|
* - [LessonRange] - the selected lesson range object, if [displayMode] == [DISPLAY_LESSON_RANGES]
|
||||||
|
*/
|
||||||
|
fun getSelected(): Any? {
|
||||||
|
return when (val tag = selected?.tag) {
|
||||||
|
0L -> null
|
||||||
|
is LessonFull ->
|
||||||
|
if (tag.displayStartTime != null)
|
||||||
|
tag.displayStartTime!! to tag.displayEndTime
|
||||||
|
else
|
||||||
|
null
|
||||||
|
is LessonRange -> tag
|
||||||
|
is Time -> tag to null
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import androidx.core.graphics.drawable.DrawableCompat
|
|||||||
import com.google.android.material.textfield.TextInputEditText
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
|
||||||
class TextInputDropDown : TextInputEditText {
|
open class TextInputDropDown : TextInputEditText {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) {
|
||||||
create(context)
|
create(context)
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ class TextInputDropDown : TextInputEditText {
|
|||||||
setText(selected?.displayText ?: selected?.text)
|
setText(selected?.displayText ?: selected?.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(context: Context) {
|
open fun create(context: Context) {
|
||||||
val drawable = context.resources.getDrawable(R.drawable.dropdown_arrow)
|
val drawable = context.resources.getDrawable(R.drawable.dropdown_arrow)
|
||||||
val wrappedDrawable = DrawableCompat.wrap(drawable)
|
val wrappedDrawable = DrawableCompat.wrap(drawable)
|
||||||
DrawableCompat.setTint(wrappedDrawable, Themes.getPrimaryTextColor(context))
|
DrawableCompat.setTint(wrappedDrawable, Themes.getPrimaryTextColor(context))
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/dialog_event_manual_date">
|
android:hint="@string/dialog_event_manual_date">
|
||||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
<pl.szczodrzynski.edziennik.ui.modules.views.DateDropdown
|
||||||
android:id="@+id/dateDropdown"
|
android:id="@+id/dateDropdown"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -38,7 +38,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:hint="@string/dialog_event_manual_time">
|
android:hint="@string/dialog_event_manual_time">
|
||||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
<pl.szczodrzynski.edziennik.ui.modules.views.TimeDropdown
|
||||||
android:id="@+id/timeDropdown"
|
android:id="@+id/timeDropdown"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -53,7 +53,7 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:hint="@string/dialog_event_manual_team">
|
android:hint="@string/dialog_event_manual_team">
|
||||||
|
|
||||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
<pl.szczodrzynski.edziennik.ui.modules.views.TeamDropdown
|
||||||
android:id="@+id/teamDropdown"
|
android:id="@+id/teamDropdown"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -158,7 +158,7 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:hint="@string/dialog_event_manual_subject">
|
android:hint="@string/dialog_event_manual_subject">
|
||||||
|
|
||||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
<pl.szczodrzynski.edziennik.ui.modules.views.SubjectDropdown
|
||||||
android:id="@+id/subjectDropdown"
|
android:id="@+id/subjectDropdown"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -173,7 +173,7 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:hint="@string/dialog_event_manual_teacher">
|
android:hint="@string/dialog_event_manual_teacher">
|
||||||
|
|
||||||
<pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
<pl.szczodrzynski.edziennik.ui.modules.views.TeacherDropdown
|
||||||
android:id="@+id/teacherDropdown"
|
android:id="@+id/teacherDropdown"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -294,6 +294,12 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/divider"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/eventsNoData"
|
android:id="@+id/eventsNoData"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -331,7 +337,6 @@
|
|||||||
android:id="@+id/eventsView"
|
android:id="@+id/eventsView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
tools:visibility="visible"
|
tools:visibility="visible"
|
||||||
tools:listitem="@layout/event_list_item" />
|
tools:listitem="@layout/event_list_item" />
|
||||||
|
@ -1233,4 +1233,8 @@
|
|||||||
<string name="grades_stats_help_text">Ocena przewidywana z danego przedmiotu jest obliczana na podstawie aktualnej średniej ważonej.\n\nOcena jest liczbą całkowitą, jaką wystawił by nauczyciel bazując na średniej. Liczba zaokrąglona jest w górę jeśli część po przecinku przekroczy ,75.\nPrzykładowo: średnie 3,75 jak również 4,74 dają w wyniku ocenę dobrą (4).\n\nŚrednia przewidywana ze wszystkich przedmiotów obejmuje obliczone w ten sposób oceny końcowe.</string>
|
<string name="grades_stats_help_text">Ocena przewidywana z danego przedmiotu jest obliczana na podstawie aktualnej średniej ważonej.\n\nOcena jest liczbą całkowitą, jaką wystawił by nauczyciel bazując na średniej. Liczba zaokrąglona jest w górę jeśli część po przecinku przekroczy ,75.\nPrzykładowo: średnie 3,75 jak również 4,74 dają w wyniku ocenę dobrą (4).\n\nŚrednia przewidywana ze wszystkich przedmiotów obejmuje obliczone w ten sposób oceny końcowe.</string>
|
||||||
<string name="grades_stats_custom_value_notice">Została ustawiona własna wartość plusa/minusa. Jeśli uważasz, że średnia się nie zgadza, kliknij Konfiguruj.</string>
|
<string name="grades_stats_custom_value_notice">Została ustawiona własna wartość plusa/minusa. Jeśli uważasz, że średnia się nie zgadza, kliknij Konfiguruj.</string>
|
||||||
<string name="configure">Konfiguruj</string>
|
<string name="configure">Konfiguruj</string>
|
||||||
|
<string name="menu_timetable_manual">Edytor planu lekcji</string>
|
||||||
|
<string name="dropdown_subject_custom">Własny przedmiot</string>
|
||||||
|
<string name="dialog_event_manual_date_choose">Wybierz datę</string>
|
||||||
|
<string name="dropdown_date_no_more_lessons">Nie ma więcej lekcji tego przedmiotu. Pobierz plan lekcji i spróbuj ponownie.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user