mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 12:56:45 -06:00
[UI] Refactor app dialogs. (#103)
* [UI] Add new base dialog classes. * [UI] Migrate dialogs to the new base classes.
This commit is contained in:
parent
fd62653d79
commit
f3e2d21b89
@ -420,7 +420,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
App.db.profileDao().getByIdNow(profile.identifier.toInt())
|
App.db.profileDao().getByIdNow(profile.identifier.toInt())
|
||||||
} ?: return@launch
|
} ?: return@launch
|
||||||
drawer.close()
|
drawer.close()
|
||||||
ProfileConfigDialog(this@MainActivity, appProfile)
|
ProfileConfigDialog(this@MainActivity, appProfile).show()
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
@ -529,7 +529,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
||||||
// force an AppSync after update
|
// force an AppSync after update
|
||||||
app.config.sync.lastAppSync = 0L
|
app.config.sync.lastAppSync = 0L
|
||||||
ChangelogDialog(this)
|
ChangelogDialog(this).show()
|
||||||
if (app.config.appVersion < 170) {
|
if (app.config.appVersion < 170) {
|
||||||
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
||||||
//startActivity(intent);
|
//startActivity(intent);
|
||||||
@ -587,7 +587,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
||||||
.withOnClickListener {
|
.withOnClickListener {
|
||||||
bottomSheet.close()
|
bottomSheet.close()
|
||||||
SyncViewListDialog(this, navTargetId)
|
SyncViewListDialog(this, navTargetId).show()
|
||||||
},
|
},
|
||||||
BottomSheetSeparatorItem(false),
|
BottomSheetSeparatorItem(false),
|
||||||
BottomSheetPrimaryItem(false)
|
BottomSheetPrimaryItem(false)
|
||||||
@ -690,7 +690,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
Type.NOT_AVAILABLE -> {
|
Type.NOT_AVAILABLE -> {
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
loadTarget(DRAWER_ITEM_HOME)
|
loadTarget(DRAWER_ITEM_HOME)
|
||||||
RegisterUnavailableDialog(this, error.status!!)
|
RegisterUnavailableDialog(this, error.status!!).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Type.API_ERROR -> {
|
Type.API_ERROR -> {
|
||||||
@ -722,7 +722,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onUpdateEvent(event: Update) {
|
fun onUpdateEvent(event: Update) {
|
||||||
EventBus.getDefault().removeStickyEvent(event)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
UpdateAvailableDialog(this, event)
|
UpdateAvailableDialog(this, event).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
@ -730,7 +730,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
EventBus.getDefault().removeStickyEvent(event)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
val error = app.availabilityManager.check(app.profile, cacheOnly = true)
|
val error = app.availabilityManager.check(app.profile, cacheOnly = true)
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
RegisterUnavailableDialog(this, error.status!!)
|
RegisterUnavailableDialog(this, error.status!!).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,7 +797,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
if (event.error.errorCode == ERROR_VULCAN_API_DEPRECATED) {
|
if (event.error.errorCode == ERROR_VULCAN_API_DEPRECATED) {
|
||||||
if (event.error.profileId != App.profileId)
|
if (event.error.profileId != App.profileId)
|
||||||
return
|
return
|
||||||
ErrorDetailsDialog(this, listOf(event.error))
|
ErrorDetailsDialog(this, listOf(event.error)).show()
|
||||||
}
|
}
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
subtitleFormat = R.string.toolbar_subtitle
|
subtitleFormat = R.string.toolbar_subtitle
|
||||||
@ -894,7 +894,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
this,
|
this,
|
||||||
extras.getString("serverMessageTitle") ?: getString(R.string.app_name),
|
extras.getString("serverMessageTitle") ?: getString(R.string.app_name),
|
||||||
extras.getString("serverMessageText") ?: ""
|
extras.getString("serverMessageText") ?: ""
|
||||||
)
|
).show()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
"feedbackMessage" -> {
|
"feedbackMessage" -> {
|
||||||
@ -917,7 +917,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
this,
|
this,
|
||||||
App.profileId,
|
App.profileId,
|
||||||
defaultDate = date
|
defaultDate = date
|
||||||
)
|
).show()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
else -> false
|
else -> false
|
||||||
|
@ -103,7 +103,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
activity,
|
activity,
|
||||||
listOf(apiError),
|
listOf(apiError),
|
||||||
R.string.error_occured
|
R.string.error_occured
|
||||||
)
|
).show()
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
null
|
null
|
||||||
|
@ -77,14 +77,14 @@ class AgendaFragment : Fragment(), CoroutineScope {
|
|||||||
activity,
|
activity,
|
||||||
app.profileId,
|
app.profileId,
|
||||||
defaultDate = AgendaFragmentDefault.selectedDate
|
defaultDate = AgendaFragmentDefault.selectedDate
|
||||||
)
|
).show()
|
||||||
},
|
},
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
.withTitle(R.string.menu_agenda_config)
|
.withTitle(R.string.menu_agenda_config)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener {
|
.withOnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
AgendaConfigDialog(activity, true, null, null)
|
AgendaConfigDialog(activity, true, null, null).show()
|
||||||
},
|
},
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
.withTitle(R.string.menu_agenda_change_view)
|
.withTitle(R.string.menu_agenda_change_view)
|
||||||
@ -124,7 +124,7 @@ class AgendaFragment : Fragment(), CoroutineScope {
|
|||||||
activity,
|
activity,
|
||||||
app.profileId,
|
app.profileId,
|
||||||
defaultDate = AgendaFragmentDefault.selectedDate
|
defaultDate = AgendaFragmentDefault.selectedDate
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
activity.gainAttention()
|
activity.gainAttention()
|
||||||
@ -188,7 +188,7 @@ class AgendaFragment : Fragment(), CoroutineScope {
|
|||||||
unreadEventDates.remove(date.value)
|
unreadEventDates.remove(date.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
DayDialog(activity, app.profileId, date)
|
DayDialog(activity, app.profileId, date).show()
|
||||||
}}
|
}}
|
||||||
|
|
||||||
b.progressBar.visibility = View.GONE
|
b.progressBar.visibility = View.GONE
|
||||||
|
@ -139,7 +139,7 @@ class AgendaFragmentDefault(
|
|||||||
val c = Calendar.getInstance()
|
val c = Calendar.getInstance()
|
||||||
c.time = dayItem.date
|
c.time = dayItem.date
|
||||||
if (c.timeInMillis == selectedDate.inMillis) {
|
if (c.timeInMillis == selectedDate.inMillis) {
|
||||||
DayDialog(activity, app.profileId, selectedDate)
|
DayDialog(activity, app.profileId, selectedDate).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,16 +147,25 @@ class AgendaFragmentDefault(
|
|||||||
val date = Date.fromCalendar(event.instanceDay)
|
val date = Date.fromCalendar(event.instanceDay)
|
||||||
|
|
||||||
when (event) {
|
when (event) {
|
||||||
is AgendaEvent -> EventDetailsDialog(activity, event.event)
|
is AgendaEvent -> EventDetailsDialog(activity, event.event).show()
|
||||||
is LessonChangesEvent -> LessonChangesDialog(activity, app.profileId, date)
|
is LessonChangesEvent -> LessonChangesDialog(
|
||||||
|
activity = activity,
|
||||||
|
profileId = app.profileId,
|
||||||
|
defaultDate = date
|
||||||
|
).show()
|
||||||
is TeacherAbsenceEvent -> TeacherAbsenceDialog(
|
is TeacherAbsenceEvent -> TeacherAbsenceDialog(
|
||||||
activity,
|
activity = activity,
|
||||||
app.profileId,
|
profileId = app.profileId,
|
||||||
date
|
date = date
|
||||||
)
|
).show()
|
||||||
is AgendaEventGroup -> DayDialog(activity, app.profileId, date, eventTypeId = event.typeId)
|
is AgendaEventGroup -> DayDialog(
|
||||||
|
activity = activity,
|
||||||
|
profileId = app.profileId,
|
||||||
|
date = date,
|
||||||
|
eventTypeId = event.typeId,
|
||||||
|
).show()
|
||||||
is BaseCalendarEvent -> if (event.isPlaceHolder)
|
is BaseCalendarEvent -> if (event.isPlaceHolder)
|
||||||
DayDialog(activity, app.profileId, date)
|
DayDialog(activity, app.profileId, date).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event is BaseEvent && event.showItemBadge) {
|
if (event is BaseEvent && event.showItemBadge) {
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.agenda
|
package pl.szczodrzynski.edziennik.ui.agenda
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
@ -23,6 +22,7 @@ import pl.szczodrzynski.edziennik.ui.agenda.lessonchanges.LessonChangesEventRend
|
|||||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceDialog
|
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEvent
|
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEvent
|
||||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEventRenderer
|
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEventRenderer
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||||
@ -30,61 +30,39 @@ import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
|||||||
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 pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class DayDialog(
|
class DayDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val profileId: Int,
|
private val profileId: Int,
|
||||||
val date: Date,
|
private val date: Date,
|
||||||
val eventTypeId: Long? = null,
|
private val eventTypeId: Long? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogDayBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "DayDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "DayDialog"
|
||||||
private lateinit var b: DialogDayBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes(): Int? = null
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogDayBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
override fun getNeutralButtonText() = R.string.add
|
||||||
|
|
||||||
private lateinit var adapter: EventListAdapter
|
private lateinit var adapter: EventListAdapter
|
||||||
|
|
||||||
init { run {
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogDayBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.setNeutralButton(R.string.add, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.onClick {
|
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
profileId,
|
profileId,
|
||||||
defaultDate = date,
|
defaultDate = date,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
|
|
||||||
update()
|
override suspend fun onShow() {
|
||||||
}}
|
|
||||||
|
|
||||||
private fun update() { launch {
|
|
||||||
b.dayDate.setText(
|
b.dayDate.setText(
|
||||||
R.string.dialog_day_date_format,
|
R.string.dialog_day_date_format,
|
||||||
Week.getFullDayName(date.weekDay),
|
Week.getFullDayName(date.weekDay),
|
||||||
@ -95,7 +73,8 @@ class DayDialog(
|
|||||||
app.db.timetableDao().getAllForDateNow(profileId, date)
|
app.db.timetableDao().getAllForDateNow(profileId, date)
|
||||||
}.filter { it.type != Lesson.TYPE_NO_LESSONS }
|
}.filter { it.type != Lesson.TYPE_NO_LESSONS }
|
||||||
|
|
||||||
if (lessons.isNotEmpty()) { run {
|
if (lessons.isNotEmpty()) {
|
||||||
|
run {
|
||||||
val startTime = lessons.first().startTime ?: return@run
|
val startTime = lessons.first().startTime ?: return@run
|
||||||
val endTime = lessons.last().endTime ?: return@run
|
val endTime = lessons.last().endTime ?: return@run
|
||||||
val diff = Time.diff(startTime, endTime)
|
val diff = Time.diff(startTime, endTime)
|
||||||
@ -110,7 +89,8 @@ class DayDialog(
|
|||||||
)
|
)
|
||||||
|
|
||||||
b.lessonsInfo.visibility = View.VISIBLE
|
b.lessonsInfo.visibility = View.VISIBLE
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val lessonChanges = withContext(Dispatchers.Default) {
|
val lessonChanges = withContext(Dispatchers.Default) {
|
||||||
app.db.timetableDao().getChangesForDateNow(profileId, date)
|
app.db.timetableDao().getChangesForDateNow(profileId, date)
|
||||||
@ -133,7 +113,7 @@ class DayDialog(
|
|||||||
date,
|
date,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.lessonChangesFrame.isVisible = lessonChanges.isNotEmpty()
|
b.lessonChangesFrame.isVisible = lessonChanges.isNotEmpty()
|
||||||
@ -158,7 +138,7 @@ class DayDialog(
|
|||||||
date,
|
date,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.teacherAbsenceFrame.isVisible = teacherAbsences.isNotEmpty()
|
b.teacherAbsenceFrame.isVisible = teacherAbsences.isNotEmpty()
|
||||||
@ -177,7 +157,7 @@ class DayDialog(
|
|||||||
it,
|
it,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
},
|
},
|
||||||
onEventEditClick = {
|
onEventEditClick = {
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
@ -186,7 +166,7 @@ class DayDialog(
|
|||||||
editingEvent = it,
|
editingEvent = it,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -217,5 +197,5 @@ class DayDialog(
|
|||||||
b.eventsNoData.visibility = View.VISIBLE
|
b.eventsNoData.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,34 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.agenda.lessonchanges
|
package pl.szczodrzynski.edziennik.ui.agenda.lessonchanges
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.withContext
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonChangeListBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogLessonChangeListBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.timetable.LessonDetailsDialog
|
import pl.szczodrzynski.edziennik.ui.timetable.LessonDetailsDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class LessonChangesDialog(
|
class LessonChangesDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val profileId: Int,
|
private val profileId: Int,
|
||||||
private val defaultDate: Date,
|
private val defaultDate: Date,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogLessonChangeListBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
const val TAG = "LessonChangeDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "LessonChangesDialog"
|
||||||
|
|
||||||
private lateinit var job: Job
|
override fun getTitle(): String = defaultDate.formattedString
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getTitleRes(): Int? = null
|
||||||
get() = job + Dispatchers.Main
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogLessonChangeListBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private lateinit var b: DialogLessonChangeListBinding
|
override fun getPositiveButtonText() = R.string.close
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
job = Job()
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
b = DialogLessonChangeListBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(defaultDate.formattedString)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
loadLessonChanges()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun loadLessonChanges() { launch {
|
|
||||||
val lessonChanges = withContext(Dispatchers.Default) {
|
val lessonChanges = withContext(Dispatchers.Default) {
|
||||||
app.db.timetableDao().getChangesForDateNow(profileId, defaultDate)
|
app.db.timetableDao().getChangesForDateNow(profileId, defaultDate)
|
||||||
}
|
}
|
||||||
@ -62,7 +41,7 @@ class LessonChangesDialog(
|
|||||||
it,
|
it,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
).apply {
|
).apply {
|
||||||
items = lessonChanges
|
items = lessonChanges
|
||||||
@ -70,7 +49,5 @@ class LessonChangesDialog(
|
|||||||
|
|
||||||
b.lessonChangeView.adapter = adapter
|
b.lessonChangeView.adapter = adapter
|
||||||
b.lessonChangeView.layoutManager = LinearLayoutManager(activity)
|
b.lessonChangeView.layoutManager = LinearLayoutManager(activity)
|
||||||
|
}
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -1,57 +1,42 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.agenda.teacherabsence
|
package pl.szczodrzynski.edziennik.ui.agenda.teacherabsence
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogTeacherAbsenceListBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogTeacherAbsenceListBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class TeacherAbsenceDialog(
|
class TeacherAbsenceDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val profileId: Int,
|
private val profileId: Int,
|
||||||
val date: Date,
|
private val date: Date,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) {
|
) : BindingDialog<DialogTeacherAbsenceListBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "TeacherAbsenceDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "TeacherAbsenceDialog"
|
||||||
|
|
||||||
private lateinit var b: DialogTeacherAbsenceListBinding
|
override fun getTitle(): String = date.formattedString
|
||||||
private lateinit var dialog: AlertDialog
|
override fun getTitleRes(): Int? = null
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogTeacherAbsenceListBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
init { run {
|
override fun getPositiveButtonText() = R.string.close
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
|
|
||||||
b = DialogTeacherAbsenceListBinding.inflate(activity.layoutInflater)
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(date.formattedString)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
|
|
||||||
|
override suspend fun onShow() {
|
||||||
b.teacherAbsenceView.setHasFixedSize(true)
|
b.teacherAbsenceView.setHasFixedSize(true)
|
||||||
b.teacherAbsenceView.layoutManager = LinearLayoutManager(activity)
|
b.teacherAbsenceView.layoutManager = LinearLayoutManager(activity)
|
||||||
|
|
||||||
app.db.teacherAbsenceDao().getAllByDate(profileId, date).observe(activity as LifecycleOwner, Observer { absenceList ->
|
app.db.teacherAbsenceDao().getAllByDate(profileId, date).observe(
|
||||||
|
activity as LifecycleOwner
|
||||||
|
) { absenceList ->
|
||||||
val adapter = TeacherAbsenceAdapter(activity, date, absenceList)
|
val adapter = TeacherAbsenceAdapter(activity, date, absenceList)
|
||||||
b.teacherAbsenceView.adapter = adapter
|
b.teacherAbsenceView.adapter = adapter
|
||||||
b.teacherAbsenceView.visibility = View.VISIBLE
|
b.teacherAbsenceView.visibility = View.VISIBLE
|
||||||
})
|
}
|
||||||
|
}
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,54 +4,33 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.attendance
|
package pl.szczodrzynski.edziennik.ui.attendance
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class AttendanceDetailsDialog(
|
class AttendanceDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val attendance: AttendanceFull,
|
private val attendance: AttendanceFull,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<AttendanceDetailsDialogBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "AttendanceDetailsDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "AttendanceDetailsDialog"
|
||||||
private lateinit var b: AttendanceDetailsDialogBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes(): Int? = null
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
AttendanceDetailsDialogBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
// local variables go here
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = AttendanceDetailsDialogBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
val manager = app.attendanceManager
|
val manager = app.attendanceManager
|
||||||
|
|
||||||
val attendanceColor = manager.getAttendanceColor(attendance)
|
val attendanceColor = manager.getAttendanceColor(attendance)
|
||||||
@ -69,5 +48,5 @@ class AttendanceDetailsDialog(
|
|||||||
onActionSelected = dialog::dismiss
|
onActionSelected = dialog::dismiss
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ class AttendanceFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener(View.OnClickListener {
|
.withOnClickListener(View.OnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
AttendanceConfigDialog(activity, true, null, null)
|
AttendanceConfigDialog(activity, true, null, null).show()
|
||||||
}),
|
}),
|
||||||
BottomSheetSeparatorItem(true),
|
BottomSheetSeparatorItem(true),
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
|
@ -96,7 +96,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
|||||||
}})
|
}})
|
||||||
|
|
||||||
adapter.onAttendanceClick = {
|
adapter.onAttendanceClick = {
|
||||||
AttendanceDetailsDialog(activity, it)
|
AttendanceDetailsDialog(activity, it).show()
|
||||||
}
|
}
|
||||||
}; return true}
|
}; return true}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
|||||||
}})
|
}})
|
||||||
|
|
||||||
adapter.onAttendanceClick = {
|
adapter.onAttendanceClick = {
|
||||||
AttendanceDetailsDialog(activity, it)
|
AttendanceDetailsDialog(activity, it).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.toggleGroup.check(when (periodSelection) {
|
b.toggleGroup.check(when (periodSelection) {
|
||||||
|
@ -5,58 +5,34 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.captcha
|
package pl.szczodrzynski.edziennik.ui.captcha
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.RecaptchaViewBinding
|
import pl.szczodrzynski.edziennik.databinding.RecaptchaViewBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
|
|
||||||
class LibrusCaptchaDialog(
|
class LibrusCaptchaDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onSuccess: (recaptchaCode: String) -> Unit,
|
private val onSuccess: (recaptchaCode: String) -> Unit,
|
||||||
val onFailure: (() -> Unit)?,
|
private val onFailure: (() -> Unit)?,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<RecaptchaViewBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
override val TAG = "LibrusCaptchaDialog"
|
||||||
private const val TAG = "LibrusCaptchaDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override fun getTitleRes(): Int? = null
|
||||||
private lateinit var b: RecaptchaViewBinding
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
private lateinit var dialog: AlertDialog
|
RecaptchaViewBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private val job = Job()
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private lateinit var checkboxBackground: Drawable
|
private lateinit var checkboxBackground: Drawable
|
||||||
private lateinit var checkboxForeground: Drawable
|
private lateinit var checkboxForeground: Drawable
|
||||||
private var success = false
|
private var success = false
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = RecaptchaViewBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
if (!success)
|
|
||||||
onFailure?.invoke()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
checkboxBackground = b.checkbox.background
|
checkboxBackground = b.checkbox.background
|
||||||
checkboxForeground = b.checkbox.foreground
|
checkboxForeground = b.checkbox.foreground
|
||||||
success = false
|
success = false
|
||||||
@ -85,7 +61,12 @@ class LibrusCaptchaDialog(
|
|||||||
b.checkbox.foreground = checkboxForeground
|
b.checkbox.foreground = checkboxForeground
|
||||||
b.progress.visibility = View.GONE
|
b.progress.visibility = View.GONE
|
||||||
}
|
}
|
||||||
)
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
if (!success)
|
||||||
|
onFailure?.invoke()
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -6,129 +6,56 @@ package pl.szczodrzynski.edziennik.ui.captcha
|
|||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.os.Handler
|
|
||||||
import android.util.Log
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.RecaptchaDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.RecaptchaDialogBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
class RecaptchaDialog(
|
class RecaptchaDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val siteKey: String,
|
private val siteKey: String,
|
||||||
val referer: String,
|
private val referer: String,
|
||||||
val autoRetry: Boolean = true,
|
private val autoRetry: Boolean = true,
|
||||||
val onSuccess: (recaptchaCode: String) -> Unit,
|
private val onSuccess: (recaptchaCode: String) -> Unit,
|
||||||
val onFailure: (() -> Unit)? = null,
|
private val onFailure: (() -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<RecaptchaDialogBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "RecaptchaDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "RecaptchaDialog"
|
||||||
private val b by lazy { RecaptchaDialogBinding.inflate(LayoutInflater.from(activity)) }
|
|
||||||
private var dialog: AlertDialog? = null
|
override fun getTitleRes(): Int? = null
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
RecaptchaDialogBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
|
||||||
private val captchaUrl = "https://www.google.com/recaptcha/api/fallback?k=$siteKey"
|
private val captchaUrl = "https://www.google.com/recaptcha/api/fallback?k=$siteKey"
|
||||||
private var success = false
|
private var success = false
|
||||||
|
|
||||||
private val job = Job()
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private var code = ""
|
private var code = ""
|
||||||
private var payload = ""
|
private var payload = ""
|
||||||
|
|
||||||
init { run {
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
if (activity.isFinishing)
|
val (title, text, bitmap) = withContext(Dispatchers.Default) {
|
||||||
return@run
|
val html = loadCaptchaHtml() ?: return@withContext null
|
||||||
app = activity.applicationContext as App
|
return@withContext loadCaptchaData(html)
|
||||||
onShowListener?.invoke(TAG)
|
} ?: run {
|
||||||
success = false
|
|
||||||
|
|
||||||
launch { initCaptcha() }
|
|
||||||
}}
|
|
||||||
|
|
||||||
private suspend fun initCaptcha() {
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(captchaUrl)
|
|
||||||
.addHeader("Referer", referer)
|
|
||||||
.addHeader("Accept-Language", "pl")
|
|
||||||
.build()
|
|
||||||
app.http.newCall(request).enqueue(object : Callback {
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val html = response.body()?.string() ?: return
|
|
||||||
Log.d(TAG, html)
|
|
||||||
parseHtml(html)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseHtml(html: String) {
|
|
||||||
launch {
|
|
||||||
"class=\"rc-imageselect-desc(?:-no-canonical)?\">(.+?) <strong>(.+?)</strong>".toRegex().find(html)?.let {
|
|
||||||
b.descTitle.text = it.groupValues[1]
|
|
||||||
b.descText.text = it.groupValues[2]
|
|
||||||
}
|
|
||||||
code = "name=\"c\" value=\"([A-z0-9-_]+)\"".toRegex().find(html)?.let { it.groupValues[1] } ?: return@launch
|
|
||||||
payload = "https://www.google.com/recaptcha/api2/payload?c=$code&k=$siteKey"
|
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
val request = Request.Builder()
|
|
||||||
.url(payload)
|
|
||||||
.addHeader("Referer", captchaUrl)
|
|
||||||
.addHeader("Accept-Language", "pl")
|
|
||||||
.build()
|
|
||||||
app.http.newCall(request).enqueue(object : Callback {
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val bitmap: Bitmap? = BitmapFactory.decodeStream(response.body()?.byteStream())
|
|
||||||
Handler(activity.mainLooper).post {
|
|
||||||
if (bitmap == null) {
|
|
||||||
onFailure?.invoke()
|
onFailure?.invoke()
|
||||||
Toast.makeText(activity, "Nie udało się załadować reCAPTCHA.", Toast.LENGTH_SHORT).show()
|
return false
|
||||||
return@post
|
|
||||||
}
|
|
||||||
b.payload.setImageBitmap(bitmap)
|
|
||||||
showDialog()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
initViews(title, text, bitmap)
|
||||||
onFailure?.invoke()
|
return true
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showDialog() {
|
override suspend fun onShow() {
|
||||||
if (dialog == null) {
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton("OK") { _, _ ->
|
|
||||||
validateAnswer()
|
|
||||||
}
|
|
||||||
.setOnDismissListener {
|
|
||||||
if (!success)
|
|
||||||
onFailure?.invoke()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
}
|
|
||||||
b.image0.isChecked = false
|
b.image0.isChecked = false
|
||||||
b.image1.isChecked = false
|
b.image1.isChecked = false
|
||||||
b.image2.isChecked = false
|
b.image2.isChecked = false
|
||||||
@ -138,11 +65,88 @@ class RecaptchaDialog(
|
|||||||
b.image6.isChecked = false
|
b.image6.isChecked = false
|
||||||
b.image7.isChecked = false
|
b.image7.isChecked = false
|
||||||
b.image8.isChecked = false
|
b.image8.isChecked = false
|
||||||
dialog!!.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateAnswer() {
|
override fun onDismiss() {
|
||||||
launch {
|
if (!success)
|
||||||
|
onFailure?.invoke()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViews(title: String, text: String, bitmap: Bitmap) {
|
||||||
|
b.descTitle.text = title
|
||||||
|
b.descText.text = text
|
||||||
|
b.payload.setImageBitmap(bitmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun loadCaptchaHtml(): String? {
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(captchaUrl)
|
||||||
|
.addHeader("Referer", referer)
|
||||||
|
.addHeader("Accept-Language", "pl")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
return suspendCoroutine { cont ->
|
||||||
|
app.http.newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
val html = response.body()?.string()
|
||||||
|
cont.resume(html)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
cont.resume(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun loadCaptchaData(html: String): Triple<String, String, Bitmap>? {
|
||||||
|
var title = ""
|
||||||
|
var text = ""
|
||||||
|
"class=\"rc-imageselect-desc(?:-no-canonical)?\">(.+?) <strong>(.+?)</strong>"
|
||||||
|
.toRegex()
|
||||||
|
.find(html)
|
||||||
|
?.let {
|
||||||
|
title = it.groupValues[1]
|
||||||
|
text = it.groupValues[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
code = "name=\"c\" value=\"([A-z0-9-_]+)\""
|
||||||
|
.toRegex()
|
||||||
|
.find(html)
|
||||||
|
?.let { it.groupValues[1] }
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
payload = "https://www.google.com/recaptcha/api2/payload?c=$code&k=$siteKey"
|
||||||
|
val request = Request.Builder()
|
||||||
|
.url(payload)
|
||||||
|
.addHeader("Referer", captchaUrl)
|
||||||
|
.addHeader("Accept-Language", "pl")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val bitmap = suspendCoroutine<Bitmap?> { cont ->
|
||||||
|
app.http.newCall(request).enqueue(object : Callback {
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
val bitmap: Bitmap? = BitmapFactory.decodeStream(response.body()?.byteStream())
|
||||||
|
if (bitmap == null) {
|
||||||
|
Toast.makeText(
|
||||||
|
activity,
|
||||||
|
"Nie udało się załadować reCAPTCHA.",
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
cont.resume(bitmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
cont.resume(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} ?: return null
|
||||||
|
|
||||||
|
return Triple(title, text, bitmap)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
val list = mutableListOf(
|
val list = mutableListOf(
|
||||||
"c=$code"
|
"c=$code"
|
||||||
)
|
)
|
||||||
@ -155,34 +159,62 @@ class RecaptchaDialog(
|
|||||||
if (b.image6.isChecked) list += "response=6"
|
if (b.image6.isChecked) list += "response=6"
|
||||||
if (b.image7.isChecked) list += "response=7"
|
if (b.image7.isChecked) list += "response=7"
|
||||||
if (b.image8.isChecked) list += "response=8"
|
if (b.image8.isChecked) list += "response=8"
|
||||||
|
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(captchaUrl)
|
.url(captchaUrl)
|
||||||
.addHeader("Referer", captchaUrl)
|
.addHeader("Referer", captchaUrl)
|
||||||
.addHeader("Accept-Language", "pl")
|
.addHeader("Accept-Language", "pl")
|
||||||
.addHeader("Origin", "https://www.google.com")
|
.addHeader("Origin", "https://www.google.com")
|
||||||
.addHeader("Content-Type", "application/x-www-form-urlencoded")
|
.addHeader("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), list.joinToString("&")))
|
.post(RequestBody.create(
|
||||||
|
MediaType.parse("application/x-www-form-urlencoded"),
|
||||||
|
list.joinToString("&"),
|
||||||
|
))
|
||||||
.build()
|
.build()
|
||||||
withContext(Dispatchers.Default) {
|
|
||||||
|
val (code, html) = withContext(Dispatchers.Default) {
|
||||||
|
return@withContext suspendCoroutine<Pair<String?, String?>> { cont ->
|
||||||
app.http.newCall(request).enqueue(object : Callback {
|
app.http.newCall(request).enqueue(object : Callback {
|
||||||
override fun onResponse(call: Call, response: Response) {
|
override fun onResponse(call: Call, response: Response) {
|
||||||
val html = response.body()?.string() ?: return
|
val html = response.body()?.string() ?: run {
|
||||||
val match = "<textarea.+?>([A-z0-9-_]+)</textarea>".toRegex().find(html)
|
cont.resume(null to null)
|
||||||
if (match == null) {
|
|
||||||
parseHtml(html)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Handler(activity.mainLooper).post {
|
val match = "<textarea.+?>([A-z0-9-_]+)</textarea>".toRegex().find(html)
|
||||||
success = true
|
if (match == null) {
|
||||||
onSuccess(match.groupValues[1])
|
cont.resume(null to html)
|
||||||
|
} else {
|
||||||
|
cont.resume(match.groupValues[1] to null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
cont.resume(null to null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when {
|
||||||
|
code != null -> {
|
||||||
|
success = true
|
||||||
|
onSuccess(code)
|
||||||
|
return DISMISS
|
||||||
|
}
|
||||||
|
html != null -> {
|
||||||
|
val (title, text, bitmap) = withContext(Dispatchers.Default) {
|
||||||
|
return@withContext loadCaptchaData(html)
|
||||||
|
} ?: run {
|
||||||
|
onFailure?.invoke()
|
||||||
|
return DISMISS
|
||||||
|
}
|
||||||
|
initViews(title, text, bitmap)
|
||||||
|
return NO_DISMISS
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
onFailure?.invoke()
|
||||||
|
return DISMISS
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ class LabPageFragment : LazyFragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.clearProfile.onClick {
|
b.clearProfile.onClick {
|
||||||
ProfileRemoveDialog(activity, App.profileId, "FAKE", noProfileRemoval = true)
|
ProfileRemoveDialog(activity, App.profileId, "FAKE", noProfileRemoval = true).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.removeHomework.onClick {
|
b.removeHomework.onClick {
|
||||||
|
@ -4,41 +4,32 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.resolveDrawable
|
import pl.szczodrzynski.edziennik.ext.resolveDrawable
|
||||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class BellSyncDialog(
|
class BellSyncDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val bellTime: Time,
|
private val bellTime: Time,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogBellSyncBinding>(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
companion object {
|
override val TAG = "BellSyncDialog"
|
||||||
const val TAG = "BellSyncDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var job: Job
|
override fun getTitleRes() = R.string.bell_sync_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogBellSyncBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private lateinit var dialog: AlertDialog
|
override fun getNeutralButtonText() = R.string.cancel
|
||||||
private lateinit var b: DialogBellSyncBinding
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
|
||||||
|
|
||||||
private var counterJob: Job? = null
|
private var counterJob: Job? = null
|
||||||
|
|
||||||
@ -50,25 +41,7 @@ class BellSyncDialog(
|
|||||||
return Pair(bellDiff, multiplier)
|
return Pair(bellDiff, multiplier)
|
||||||
}
|
}
|
||||||
|
|
||||||
init { apply {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@apply
|
|
||||||
job = Job()
|
|
||||||
b = DialogBellSyncBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.bell_sync_title)
|
|
||||||
.setView(b.root)
|
|
||||||
.setNeutralButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
counterJob?.cancel()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
initView()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
b.bellSyncButton.setOnClickListener {
|
b.bellSyncButton.setOnClickListener {
|
||||||
val (bellDiff, multiplier) = actualBellDiff
|
val (bellDiff, multiplier) = actualBellDiff
|
||||||
val bellDiffText = (if (multiplier == -1) '-' else '+') + bellDiff.stringHMS
|
val bellDiffText = (if (multiplier == -1) '-' else '+') + bellDiff.stringHMS
|
||||||
@ -90,12 +63,15 @@ class BellSyncDialog(
|
|||||||
b.bellSyncButton.setImageDrawable(R.drawable.ic_bell_wtf.resolveDrawable(app)) // wtf
|
b.bellSyncButton.setImageDrawable(R.drawable.ic_bell_wtf.resolveDrawable(app)) // wtf
|
||||||
}
|
}
|
||||||
|
|
||||||
launch {
|
|
||||||
counterJob = startCoroutineTimer(repeatMillis = 500) {
|
counterJob = startCoroutineTimer(repeatMillis = 500) {
|
||||||
val (bellDiff, multiplier) = actualBellDiff
|
val (bellDiff, multiplier) = actualBellDiff
|
||||||
val bellDiffText = (if (multiplier == -1) '-' else '+') + bellDiff.stringHMS
|
val bellDiffText = (if (multiplier == -1) '-' else '+') + bellDiff.stringHMS
|
||||||
b.bellSyncHowto.text = app.getString(R.string.bell_sync_howto, bellTime.stringHM, bellDiffText)
|
b.bellSyncHowto.text =
|
||||||
|
app.getString(R.string.bell_sync_howto, bellTime.stringHM, bellDiffText)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
counterJob?.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
@ -13,66 +13,62 @@ import pl.szczodrzynski.edziennik.MainActivity
|
|||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
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 kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class BellSyncTimeChooseDialog(
|
class BellSyncTimeChooseDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogBellSyncTimeChooseBinding>(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "BellSyncTimeChooseDialog"
|
|
||||||
|
|
||||||
private const val MAX_DIFF_MINUTES = 10
|
private const val MAX_DIFF_MINUTES = 10
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var job: Job
|
override val TAG = "BellSyncTimeChooseDialog"
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private lateinit var dialog: AlertDialog
|
override fun getTitleRes() = R.string.bell_sync_title
|
||||||
private lateinit var b: DialogBellSyncTimeChooseBinding
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogBellSyncTimeChooseBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNeutralButtonText() = R.string.reset
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
private val today = Date.getToday()
|
private val today = Date.getToday()
|
||||||
private val selectedTime: Time?
|
private val selectedTime: Time?
|
||||||
get() = b.timeDropdown.selected?.tag as Time?
|
get() = b.timeDropdown.selected?.tag as Time?
|
||||||
|
|
||||||
init { apply {
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@apply
|
|
||||||
job = Job()
|
|
||||||
b = DialogBellSyncTimeChooseBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.bell_sync_title)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
selectedTime?.let {
|
selectedTime?.let {
|
||||||
BellSyncDialog(activity, it)
|
BellSyncDialog(activity, it).show()
|
||||||
}
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
.apply {
|
|
||||||
setButton(AlertDialog.BUTTON_NEUTRAL, app.getString(R.string.reset)) { _, _ ->
|
|
||||||
showResetDialog()
|
|
||||||
}
|
}
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
|
|
||||||
initView()
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
}}
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
.setTitle(R.string.bell_sync_title)
|
||||||
|
.setMessage(R.string.bell_sync_reset_confirm)
|
||||||
|
.setPositiveButton(R.string.yes) { dialog, _ ->
|
||||||
|
app.config.timetable.bellSyncDiff = null
|
||||||
|
app.config.timetable.bellSyncMultiplier = 0
|
||||||
|
|
||||||
private fun initView() {
|
dialog.dismiss()
|
||||||
|
reload()
|
||||||
|
if (activity is MainActivity)
|
||||||
|
activity.reloadTarget()
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.no, null)
|
||||||
|
.show()
|
||||||
|
return NO_DISMISS
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
b.bellSyncHowto.text = app.getString(R.string.bell_sync_choose_howto)
|
b.bellSyncHowto.text = app.getString(R.string.bell_sync_choose_howto)
|
||||||
|
|
||||||
app.config.timetable.bellSyncDiff?.let { bellDiff ->
|
app.config.timetable.bellSyncDiff?.let { bellDiff ->
|
||||||
@ -84,7 +80,7 @@ class BellSyncTimeChooseDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTimeList()
|
return loadTimeList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkForLessons(timeList: List<Time>): Boolean {
|
private fun checkForLessons(timeList: List<Time>): Boolean {
|
||||||
@ -98,7 +94,7 @@ class BellSyncTimeChooseDialog(
|
|||||||
} else false
|
} else false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadTimeList() { launch {
|
private suspend fun loadTimeList(): Boolean {
|
||||||
val timeItems = withContext(Dispatchers.Default) {
|
val timeItems = withContext(Dispatchers.Default) {
|
||||||
val lessons = app.db.timetableDao().getAllForDateNow(App.profileId, today)
|
val lessons = app.db.timetableDao().getAllForDateNow(App.profileId, today)
|
||||||
val items = mutableListOf<TextInputDropDown.Item>()
|
val items = mutableListOf<TextInputDropDown.Item>()
|
||||||
@ -106,17 +102,21 @@ class BellSyncTimeChooseDialog(
|
|||||||
lessons.forEach {
|
lessons.forEach {
|
||||||
if (it.type != Lesson.TYPE_NO_LESSONS &&
|
if (it.type != Lesson.TYPE_NO_LESSONS &&
|
||||||
it.type != Lesson.TYPE_CANCELLED &&
|
it.type != Lesson.TYPE_CANCELLED &&
|
||||||
it.type != Lesson.TYPE_SHIFTED_SOURCE) {
|
it.type != Lesson.TYPE_SHIFTED_SOURCE
|
||||||
|
) {
|
||||||
|
|
||||||
items += TextInputDropDown.Item(
|
items += TextInputDropDown.Item(
|
||||||
it.displayStartTime?.value?.toLong() ?: return@forEach,
|
it.displayStartTime?.value?.toLong() ?: return@forEach,
|
||||||
app.getString(R.string.bell_sync_lesson_item, it.displaySubjectName, it.displayStartTime?.stringHM),
|
app.getString(R.string.bell_sync_lesson_item,
|
||||||
|
it.displaySubjectName,
|
||||||
|
it.displayStartTime?.stringHM),
|
||||||
tag = it.displayStartTime
|
tag = it.displayStartTime
|
||||||
)
|
)
|
||||||
|
|
||||||
items += TextInputDropDown.Item(
|
items += TextInputDropDown.Item(
|
||||||
it.displayEndTime?.value?.toLong() ?: return@forEach,
|
it.displayEndTime?.value?.toLong() ?: return@forEach,
|
||||||
app.getString(R.string.bell_sync_break_item, it.displayEndTime?.stringHM),
|
app.getString(R.string.bell_sync_break_item,
|
||||||
|
it.displayEndTime?.stringHM),
|
||||||
tag = it.displayEndTime
|
tag = it.displayEndTime
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -130,8 +130,9 @@ class BellSyncTimeChooseDialog(
|
|||||||
MaterialAlertDialogBuilder(activity)
|
MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.bell_sync_title)
|
.setTitle(R.string.bell_sync_title)
|
||||||
.setMessage(R.string.bell_sync_cannot_now)
|
.setMessage(R.string.bell_sync_cannot_now)
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show()
|
.show()
|
||||||
|
return false
|
||||||
} else {
|
} else {
|
||||||
b.timeDropdown.clear()
|
b.timeDropdown.clear()
|
||||||
b.timeDropdown.append(timeItems)
|
b.timeDropdown.append(timeItems)
|
||||||
@ -144,24 +145,7 @@ class BellSyncTimeChooseDialog(
|
|||||||
|
|
||||||
b.timeDropdown.isEnabled = true
|
b.timeDropdown.isEnabled = true
|
||||||
// TODO Fix popup cutting off
|
// TODO Fix popup cutting off
|
||||||
|
|
||||||
dialog.show()
|
|
||||||
}
|
}
|
||||||
}}
|
return true
|
||||||
|
|
||||||
private fun showResetDialog() {
|
|
||||||
MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.bell_sync_title)
|
|
||||||
.setMessage(R.string.bell_sync_reset_confirm)
|
|
||||||
.setPositiveButton(R.string.yes) { confirmDialog, _ ->
|
|
||||||
app.config.timetable.bellSyncDiff = null
|
|
||||||
app.config.timetable.bellSyncMultiplier = 0
|
|
||||||
|
|
||||||
confirmDialog.dismiss()
|
|
||||||
initView()
|
|
||||||
if (activity is MainActivity) activity.reloadTarget()
|
|
||||||
}
|
|
||||||
.setNegativeButton(R.string.no) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,43 +4,29 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import android.widget.ScrollView
|
import android.widget.ScrollView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.ext.dp
|
import pl.szczodrzynski.edziennik.ext.dp
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod
|
import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod
|
||||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class ChangelogDialog(
|
class ChangelogDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : ViewDialog<ScrollView>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "ChangelogDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "ChangelogDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.whats_new
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getPositiveButtonText() = R.string.close
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() = Unit
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
override fun getRootView(): ScrollView {
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
val textView = TextView(activity)
|
val textView = TextView(activity)
|
||||||
textView.setPadding(24.dp, 24.dp, 24.dp, 0)
|
textView.setPadding(24.dp, 24.dp, 24.dp, 0)
|
||||||
|
|
||||||
@ -49,29 +35,22 @@ class ChangelogDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val commitsUrlPrefix = "https://github.com/szkolny-eu/szkolny-android/commits?author="
|
val commitsUrlPrefix = "https://github.com/szkolny-eu/szkolny-android/commits?author="
|
||||||
text = text.replace("""\[(.+?)]\(@([A-z0-9-]+)\)""".toRegex(), "<a href=\"$commitsUrlPrefix$2\">$1</a>")
|
text = text.replace(
|
||||||
text = text.replace("""\s@([A-z0-9-]+)""".toRegex(), " <a href=\"$commitsUrlPrefix$1\">@$1</a>")
|
regex = """\[(.+?)]\(@([A-z0-9-]+)\)""".toRegex(),
|
||||||
|
replacement = "<a href=\"$commitsUrlPrefix$2\">$1</a>"
|
||||||
|
)
|
||||||
|
text = text.replace(
|
||||||
|
regex = """\s@([A-z0-9-]+)""".toRegex(),
|
||||||
|
replacement = " <a href=\"$commitsUrlPrefix$1\">@$1</a>"
|
||||||
|
)
|
||||||
|
|
||||||
val html = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
textView.text = BetterHtml.fromHtml(activity, text)
|
||||||
text
|
|
||||||
else
|
|
||||||
text.replace("<li>", "<br><li> - ")
|
|
||||||
textView.text = BetterHtml.fromHtml(activity, html)
|
|
||||||
|
|
||||||
textView.movementMethod = BetterLinkMovementMethod.getInstance()
|
textView.movementMethod = BetterLinkMovementMethod.getInstance()
|
||||||
|
|
||||||
val scrollView = ScrollView(activity)
|
val scrollView = ScrollView(activity)
|
||||||
scrollView.addView(textView)
|
scrollView.addView(textView)
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
return scrollView
|
||||||
.setTitle(R.string.whats_new)
|
|
||||||
.setView(scrollView)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
}
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -5,51 +5,41 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class ProfileRemoveDialog(
|
class ProfileRemoveDialog(
|
||||||
val activity: MainActivity,
|
activity: AppCompatActivity,
|
||||||
val profileId: Int,
|
val profileId: Int,
|
||||||
val profileName: String,
|
val profileName: String,
|
||||||
val noProfileRemoval: Boolean = false,
|
val noProfileRemoval: Boolean = false,
|
||||||
val onRemove: (() -> Unit)? = null
|
val onRemove: (() -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
companion object {
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
private const val TAG = "ProfileRemoveDialog"
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var job: Job
|
override val TAG = "ProfileRemoveDialog"
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override fun getTitleRes() = R.string.profile_menu_remove_confirm
|
||||||
private lateinit var b: DialogLessonDetailsBinding
|
override fun getMessageFormat() =
|
||||||
private lateinit var dialog: AlertDialog
|
R.string.profile_menu_remove_confirm_text_format to listOf(
|
||||||
|
profileName,
|
||||||
|
profileName
|
||||||
|
)
|
||||||
|
|
||||||
init { run {
|
override fun isCancelable() = false
|
||||||
job = Job()
|
override fun getPositiveButtonText() = R.string.remove
|
||||||
|
override fun getNeutralButtonText() = R.string.cancel
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
override suspend fun onShow() = Unit
|
||||||
.setTitle(R.string.profile_menu_remove_confirm)
|
|
||||||
.setMessage(activity.getString(R.string.profile_menu_remove_confirm_text_format, profileName, profileName))
|
|
||||||
.setPositiveButton(R.string.remove) { _, _ ->
|
|
||||||
removeProfile()
|
|
||||||
}
|
|
||||||
.setNeutralButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setCancelable(false)
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun removeProfile() { launch {
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
val deferred = async(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
val profileObject = app.db.profileDao().getByIdNow(profileId) ?: return@async
|
val profileObject = app.db.profileDao().getByIdNow(profileId) ?: return@withContext
|
||||||
app.db.announcementDao().clear(profileId)
|
app.db.announcementDao().clear(profileId)
|
||||||
app.db.attendanceDao().clear(profileId)
|
app.db.attendanceDao().clear(profileId)
|
||||||
app.db.attendanceTypeDao().clear(profileId)
|
app.db.attendanceTypeDao().clear(profileId)
|
||||||
@ -77,12 +67,13 @@ class ProfileRemoveDialog(
|
|||||||
app.db.metadataDao().deleteAll(profileId)
|
app.db.metadataDao().deleteAll(profileId)
|
||||||
|
|
||||||
if (noProfileRemoval)
|
if (noProfileRemoval)
|
||||||
return@async
|
return@withContext
|
||||||
|
|
||||||
app.db.configDao().clear(profileId)
|
app.db.configDao().clear(profileId)
|
||||||
|
|
||||||
val loginStoreId = profileObject.loginStoreId
|
val loginStoreId = profileObject.loginStoreId
|
||||||
val profilesUsingLoginStore = app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
val profilesUsingLoginStore =
|
||||||
|
app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
||||||
if (profilesUsingLoginStore.size == 1) {
|
if (profilesUsingLoginStore.size == 1) {
|
||||||
app.db.loginStoreDao().remove(loginStoreId)
|
app.db.loginStoreDao().remove(loginStoreId)
|
||||||
}
|
}
|
||||||
@ -92,10 +83,13 @@ class ProfileRemoveDialog(
|
|||||||
app.profileLoadLast { }
|
app.profileLoadLast { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
deferred.await()
|
|
||||||
dialog.dismiss()
|
if (activity is MainActivity)
|
||||||
activity.reloadTarget()
|
activity.reloadTarget()
|
||||||
|
|
||||||
Toast.makeText(activity, R.string.dialog_profile_remove_success, Toast.LENGTH_LONG).show()
|
Toast.makeText(activity, R.string.dialog_profile_remove_success, Toast.LENGTH_LONG).show()
|
||||||
onRemove?.invoke()
|
onRemove?.invoke()
|
||||||
}}
|
|
||||||
|
return DISMISS
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,59 +4,36 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import me.dm7.barcodescanner.zxing.ZXingScannerView
|
import me.dm7.barcodescanner.zxing.ZXingScannerView
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.ext.dp
|
import pl.szczodrzynski.edziennik.ext.dp
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog
|
||||||
|
|
||||||
class QrScannerDialog(
|
class QrScannerDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onCodeScanned: (text: String) -> Unit,
|
val onCodeScanned: (text: String) -> Unit,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : ViewDialog<ZXingScannerView>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "QrScannerDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "QrScannerDialog"
|
||||||
private lateinit var scannerView: ZXingScannerView
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.qr_scanner_dialog_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getPositiveButtonText() = R.string.close
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
init { run {
|
override fun getRootView(): ZXingScannerView {
|
||||||
if (activity.isFinishing)
|
val scannerView = ZXingScannerView(activity)
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
scannerView = ZXingScannerView(activity)
|
|
||||||
scannerView.setPadding(0, 16.dp, 2.dp, 0)
|
scannerView.setPadding(0, 16.dp, 2.dp, 0)
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
return scannerView
|
||||||
.setTitle(R.string.qr_scanner_dialog_title)
|
|
||||||
.setView(scannerView)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
}
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
scannerView.setResultHandler {
|
override suspend fun onShow() {
|
||||||
scannerView.stopCamera()
|
root.setResultHandler {
|
||||||
|
root.stopCamera()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
onCodeScanned(it.text)
|
onCodeScanned(it.text)
|
||||||
}
|
}
|
||||||
scannerView.startCamera()
|
root.startCamera()
|
||||||
}}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,59 +7,45 @@ package pl.szczodrzynski.edziennik.ui.dialogs
|
|||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.SpannableStringBuilder
|
import android.text.SpannableStringBuilder
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.StyledTextDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.StyledTextDialogBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.DefaultTextStyles
|
import pl.szczodrzynski.edziennik.utils.DefaultTextStyles
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode.SIMPLE
|
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode.SIMPLE
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.StylingConfig
|
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.StylingConfig
|
||||||
|
|
||||||
class StyledTextDialog(
|
class StyledTextDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val initialText: Editable?,
|
val initialText: Editable?,
|
||||||
val onSuccess: (text: Editable) -> Unit,
|
val onSuccess: (text: Editable) -> Unit,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) {
|
) : BindingDialog<StyledTextDialogBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "StyledTextDialog"
|
override val TAG = "StyledTextDialog"
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
|
||||||
private lateinit var b: StyledTextDialogBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
private lateinit var config: StylingConfig
|
private lateinit var config: StylingConfig
|
||||||
|
|
||||||
private val manager
|
private val manager
|
||||||
get() = app.textStylingManager
|
get() = app.textStylingManager
|
||||||
|
|
||||||
init {
|
override fun getTitleRes() = R.string.styled_text_dialog_title
|
||||||
show()
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
}
|
StyledTextDialogBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
fun show() {
|
override fun getPositiveButtonText() = R.string.save
|
||||||
if (activity.isFinishing)
|
override fun getNeutralButtonText() = R.string.cancel
|
||||||
return
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = StyledTextDialogBinding.inflate(activity.layoutInflater)
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
.setTitle(R.string.styled_text_dialog_title)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.save) { _, _ ->
|
|
||||||
onSuccess(b.editText.text ?: SpannableStringBuilder(""))
|
onSuccess(b.editText.text ?: SpannableStringBuilder(""))
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
|
override suspend fun onShow() {
|
||||||
config = StylingConfig(
|
config = StylingConfig(
|
||||||
editText = b.editText,
|
editText = b.editText,
|
||||||
fontStyleGroup = b.fontStyle.styles,
|
fontStyleGroup = b.fontStyle.styles,
|
||||||
|
@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.appcompat.app.AlertDialog.*
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
|
import pl.szczodrzynski.edziennik.ext.setMessage
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
abstract class BaseDialog(
|
||||||
|
protected val activity: AppCompatActivity,
|
||||||
|
protected val onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
protected val onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : CoroutineScope {
|
||||||
|
companion object {
|
||||||
|
const val DISMISS = true
|
||||||
|
const val NO_DISMISS = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("PropertyName")
|
||||||
|
abstract val TAG: String
|
||||||
|
|
||||||
|
protected lateinit var app: App
|
||||||
|
protected lateinit var dialog: AlertDialog
|
||||||
|
|
||||||
|
private val job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
|
private var items = emptyList<Any>()
|
||||||
|
private var itemSelected: Any? = null
|
||||||
|
private var itemStates = BooleanArray(0)
|
||||||
|
|
||||||
|
protected open fun getTitle(): CharSequence? = null
|
||||||
|
protected abstract fun getTitleRes(): Int?
|
||||||
|
protected open fun getMessage(): CharSequence? = null
|
||||||
|
protected open fun getMessageRes(): Int? = null
|
||||||
|
protected open fun getMessageFormat(): Pair<Int, List<CharSequence>>? = null
|
||||||
|
protected open fun getView(): View? = null
|
||||||
|
open fun isCancelable() = true
|
||||||
|
open fun getPositiveButtonText(): Int? = null
|
||||||
|
open fun getNeutralButtonText(): Int? = null
|
||||||
|
open fun getNegativeButtonText(): Int? = null
|
||||||
|
|
||||||
|
protected open fun getSingleChoiceItems(): Map<CharSequence, Any>? = null
|
||||||
|
protected open fun getMultiChoiceItems(): Map<CharSequence, Any>? = null
|
||||||
|
protected open fun getDefaultSelectedItem(): Any? = null
|
||||||
|
protected open fun getDefaultSelectedItems(): Set<Any> = emptySet()
|
||||||
|
|
||||||
|
open suspend fun onPositiveClick() = true
|
||||||
|
open suspend fun onNeutralClick() = true
|
||||||
|
open suspend fun onNegativeClick() = true
|
||||||
|
open suspend fun onSingleSelectionChanged(item: Any?) = Unit
|
||||||
|
open suspend fun onMultiSelectionChanged(items: Set<Any>) = Unit
|
||||||
|
|
||||||
|
protected open suspend fun onBeforeShow() = true
|
||||||
|
protected abstract suspend fun onShow()
|
||||||
|
protected open fun onDismiss() = Unit
|
||||||
|
|
||||||
|
fun show() {
|
||||||
|
if (activity.isFinishing)
|
||||||
|
return
|
||||||
|
onShowListener?.invoke(TAG)
|
||||||
|
app = activity.applicationContext as App
|
||||||
|
dialog = MaterialAlertDialogBuilder(activity)
|
||||||
|
.also(this::configure)
|
||||||
|
.setCancelable(isCancelable())
|
||||||
|
.setOnDismissListener {
|
||||||
|
onDismiss()
|
||||||
|
onDismissListener?.invoke(TAG)
|
||||||
|
}
|
||||||
|
.create()
|
||||||
|
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun reload() {
|
||||||
|
launch {
|
||||||
|
if (activity.isFinishing)
|
||||||
|
return@launch
|
||||||
|
if (!onBeforeShow()) {
|
||||||
|
dialog.dismiss()
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
dialog.show()
|
||||||
|
setButtons()
|
||||||
|
onShow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun configure(md: MaterialAlertDialogBuilder) {
|
||||||
|
getTitle()?.let {
|
||||||
|
md.setTitle(it)
|
||||||
|
}
|
||||||
|
getTitleRes()?.let {
|
||||||
|
md.setTitle(it)
|
||||||
|
}
|
||||||
|
getPositiveButtonText()?.let {
|
||||||
|
md.setPositiveButton(it, null)
|
||||||
|
}
|
||||||
|
getNeutralButtonText()?.let {
|
||||||
|
md.setNeutralButton(it, null)
|
||||||
|
}
|
||||||
|
getNegativeButtonText()?.let {
|
||||||
|
md.setNegativeButton(it, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
getMessage()?.let {
|
||||||
|
md.setMessage(it)
|
||||||
|
}
|
||||||
|
getMessageRes()?.let {
|
||||||
|
md.setMessage(it)
|
||||||
|
}
|
||||||
|
getMessageFormat()?.let { (stringId, formatArgs) ->
|
||||||
|
md.setMessage(stringId, *formatArgs.toTypedArray())
|
||||||
|
}
|
||||||
|
getView()?.let {
|
||||||
|
md.setView(it)
|
||||||
|
}
|
||||||
|
|
||||||
|
getSingleChoiceItems()?.let { map ->
|
||||||
|
val default = getDefaultSelectedItem()
|
||||||
|
val defaultIndex = map.values.indexOf(default)
|
||||||
|
md.setSingleChoiceItems(map.keys.toTypedArray(), defaultIndex) { _, which ->
|
||||||
|
launch {
|
||||||
|
itemSelected = items[which]
|
||||||
|
onSingleSelectionChanged(getSingleSelection())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items = map.values.toList()
|
||||||
|
itemSelected = default
|
||||||
|
md.setMessage(null)
|
||||||
|
}
|
||||||
|
getMultiChoiceItems()?.let { map ->
|
||||||
|
val default = getDefaultSelectedItems()
|
||||||
|
val defaultStates = map.values.map {
|
||||||
|
it in default
|
||||||
|
}.toBooleanArray()
|
||||||
|
md.setMultiChoiceItems(map.keys.toTypedArray(),
|
||||||
|
defaultStates) { _, position, isChecked ->
|
||||||
|
launch {
|
||||||
|
itemStates[position] = isChecked
|
||||||
|
onMultiSelectionChanged(getMultiSelection())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items = map.values.toList()
|
||||||
|
itemStates = defaultStates
|
||||||
|
md.setMessage(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setButtons() {
|
||||||
|
dialog.getButton(BUTTON_POSITIVE)?.onClick {
|
||||||
|
launch {
|
||||||
|
if (onPositiveClick())
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.getButton(BUTTON_NEUTRAL)?.onClick {
|
||||||
|
launch {
|
||||||
|
if (onNeutralClick())
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.getButton(BUTTON_NEGATIVE)?.onClick {
|
||||||
|
launch {
|
||||||
|
if (onNegativeClick())
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun getSingleSelection() = itemSelected
|
||||||
|
protected fun getMultiSelection(): Set<Any> {
|
||||||
|
return itemStates.mapIndexed { position, isChecked ->
|
||||||
|
if (isChecked)
|
||||||
|
items[position]
|
||||||
|
else
|
||||||
|
null
|
||||||
|
}.filterNotNull().toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun dismiss() {
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
|
||||||
|
abstract class BindingDialog<B : ViewBinding>(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : ViewDialog<View>(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
|
protected lateinit var b: B
|
||||||
|
protected abstract fun inflate(layoutInflater: LayoutInflater): B
|
||||||
|
|
||||||
|
final override fun getRootView(): View {
|
||||||
|
b = inflate(activity.layoutInflater)
|
||||||
|
return b.root
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
|
||||||
|
abstract class ConfigDialog<B : ViewBinding>(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
private val reloadOnDismiss: Boolean = true,
|
||||||
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : BindingDialog<B>(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
|
final override fun getPositiveButtonText() = R.string.ok
|
||||||
|
final override suspend fun onShow() = Unit
|
||||||
|
|
||||||
|
protected val config by lazy { app.config.grades }
|
||||||
|
|
||||||
|
protected open suspend fun loadConfig() = Unit
|
||||||
|
protected open suspend fun saveConfig() = Unit
|
||||||
|
protected open fun initView() = Unit
|
||||||
|
|
||||||
|
final override suspend fun onBeforeShow(): Boolean {
|
||||||
|
initView()
|
||||||
|
loadConfig()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun onDismiss() {
|
||||||
|
launch {
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
if (reloadOnDismiss && activity is MainActivity)
|
||||||
|
activity.reloadTarget()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
abstract class ViewDialog<V : View>(
|
||||||
|
activity: AppCompatActivity,
|
||||||
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
|
onDismissListener: ((tag: String) -> Unit)? = null
|
||||||
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
|
protected lateinit var root: V
|
||||||
|
protected abstract fun getRootView(): V
|
||||||
|
|
||||||
|
final override fun getMessage() = null
|
||||||
|
final override fun getMessageFormat() = null
|
||||||
|
final override fun getView(): View {
|
||||||
|
root = getRootView()
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
@ -12,57 +12,48 @@ import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.REGISTRATION_ENABLED
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.REGISTRATION_ENABLED
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogConfigAgendaBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogConfigAgendaBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onChange
|
import pl.szczodrzynski.edziennik.ext.onChange
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AgendaConfigDialog(
|
class AgendaConfigDialog(
|
||||||
private val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val reloadOnDismiss: Boolean = true,
|
reloadOnDismiss: Boolean = true,
|
||||||
private val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
private val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : ConfigDialog<DialogConfigAgendaBinding>(
|
||||||
|
activity,
|
||||||
|
reloadOnDismiss,
|
||||||
|
onShowListener,
|
||||||
|
onDismissListener,
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
const val TAG = "AgendaConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "AgendaConfigDialog"
|
||||||
private val config by lazy { app.config.ui }
|
|
||||||
|
override fun getTitleRes() = R.string.menu_agenda_config
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogConfigAgendaBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private val profileConfig by lazy { app.config.forProfile().ui }
|
private val profileConfig by lazy { app.config.forProfile().ui }
|
||||||
|
|
||||||
private lateinit var b: DialogConfigAgendaBinding
|
override suspend fun loadConfig() {
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
b = DialogConfigAgendaBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.menu_agenda_config)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
saveConfig()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
loadConfig()
|
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun loadConfig() {
|
|
||||||
b.config = profileConfig
|
b.config = profileConfig
|
||||||
b.isAgendaMode = profileConfig.agendaViewType == Profile.AGENDA_DEFAULT
|
b.isAgendaMode = profileConfig.agendaViewType == Profile.AGENDA_DEFAULT
|
||||||
|
|
||||||
b.eventSharingEnabled.isChecked = app.profile.enableSharedEvents
|
b.eventSharingEnabled.isChecked =
|
||||||
&& app.profile.registration == REGISTRATION_ENABLED
|
app.profile.enableSharedEvents && app.profile.registration == REGISTRATION_ENABLED
|
||||||
b.eventSharingEnabled.onChange { _, isChecked ->
|
b.eventSharingEnabled.onChange { _, isChecked ->
|
||||||
if (isChecked && app.profile.registration != REGISTRATION_ENABLED) {
|
if (isChecked && app.profile.registration != REGISTRATION_ENABLED) {
|
||||||
b.eventSharingEnabled.isChecked = false
|
b.eventSharingEnabled.isChecked = false
|
||||||
val dialog = RegistrationConfigDialog(activity, app.profile, onChangeListener = { enabled ->
|
val dialog = RegistrationConfigDialog(
|
||||||
|
activity,
|
||||||
|
app.profile,
|
||||||
|
onChangeListener = { enabled ->
|
||||||
b.eventSharingEnabled.isChecked = enabled
|
b.eventSharingEnabled.isChecked = enabled
|
||||||
setEventSharingEnabled(enabled)
|
setEventSharingEnabled(enabled)
|
||||||
}, onShowListener, onDismissListener)
|
},
|
||||||
|
onShowListener,
|
||||||
|
onDismissListener,
|
||||||
|
)
|
||||||
dialog.showEnableDialog()
|
dialog.showEnableDialog()
|
||||||
return@onChange
|
return@onChange
|
||||||
}
|
}
|
||||||
@ -86,8 +77,4 @@ class AgendaConfigDialog(
|
|||||||
.setPositiveButton(R.string.ok, null)
|
.setPositiveButton(R.string.ok, null)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveConfig() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,68 +4,40 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class AppLanguageDialog(
|
class AppLanguageDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
override val TAG = "AppLanguageDialog"
|
||||||
private const val TAG = "AppLanguageDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override fun getTitleRes() = R.string.app_language_dialog_title
|
||||||
private lateinit var dialog: AlertDialog
|
override fun getMessage() = activity.getString(R.string.app_language_dialog_text)
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
private val job = Job()
|
override fun getSingleChoiceItems(): Map<CharSequence, Any> = mapOf(
|
||||||
override val coroutineContext: CoroutineContext
|
R.string.language_system to "",
|
||||||
get() = job + Dispatchers.Main
|
R.string.language_polish to "pl",
|
||||||
|
R.string.language_english to "en",
|
||||||
|
R.string.language_german to "de",
|
||||||
|
).mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
|
||||||
// local variables go here
|
override fun getDefaultSelectedItem() = app.config.ui.language
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() = Unit
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
val languages = mapOf(
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
null to R.string.language_system,
|
val language = getSingleSelection() as? String ?: return DISMISS
|
||||||
"pl" to R.string.language_polish,
|
if (language.isEmpty())
|
||||||
"en" to R.string.language_english,
|
app.config.ui.language = null
|
||||||
"de" to R.string.language_german
|
else
|
||||||
)
|
app.config.ui.language = language
|
||||||
val languageIds = languages.map { it.key }
|
|
||||||
val languageNames = languages.map {
|
|
||||||
activity.getString(it.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.app_language_dialog_title)
|
|
||||||
//.setMessage(R.string.settings_about_language_dialog_text)
|
|
||||||
.setSingleChoiceItems(
|
|
||||||
languageNames.toTypedArray(),
|
|
||||||
languageIds.indexOf(app.config.ui.language),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
|
||||||
val which = dialog.listView.checkedItemPosition
|
|
||||||
|
|
||||||
app.config.ui.language = languageIds[which]
|
|
||||||
activity.recreate()
|
activity.recreate()
|
||||||
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,64 +4,40 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.AttendanceConfigDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceConfigDialogBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onChange
|
import pl.szczodrzynski.edziennik.ext.onChange
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||||
|
|
||||||
class AttendanceConfigDialog(
|
class AttendanceConfigDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val reloadOnDismiss: Boolean = true,
|
reloadOnDismiss: Boolean = true,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : ConfigDialog<AttendanceConfigDialogBinding>(
|
||||||
|
activity,
|
||||||
|
reloadOnDismiss,
|
||||||
|
onShowListener,
|
||||||
|
onDismissListener,
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
const val TAG = "GradesConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "AttendanceConfigDialog"
|
||||||
|
|
||||||
|
override fun getTitleRes() = R.string.menu_attendance_config
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
AttendanceConfigDialogBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private val profileConfig by lazy { app.config.getFor(app.profileId).attendance }
|
private val profileConfig by lazy { app.config.getFor(app.profileId).attendance }
|
||||||
|
|
||||||
private lateinit var b: AttendanceConfigDialogBinding
|
override suspend fun loadConfig() {
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
b = AttendanceConfigDialogBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.menu_attendance_config)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
saveConfig()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
initView()
|
|
||||||
loadConfig()
|
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
|
||||||
private fun loadConfig() {
|
|
||||||
b.useSymbols.isChecked = profileConfig.useSymbols
|
b.useSymbols.isChecked = profileConfig.useSymbols
|
||||||
b.groupConsecutiveDays.isChecked = profileConfig.groupConsecutiveDays
|
b.groupConsecutiveDays.isChecked = profileConfig.groupConsecutiveDays
|
||||||
b.showPresenceInMonth.isChecked = profileConfig.showPresenceInMonth
|
b.showPresenceInMonth.isChecked = profileConfig.showPresenceInMonth
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveConfig() {
|
override fun initView() {
|
||||||
// nothing to do here, yet
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initView() {
|
|
||||||
b.useSymbols.onChange { _, isChecked ->
|
b.useSymbols.onChange { _, isChecked ->
|
||||||
profileConfig.useSymbols = isChecked
|
profileConfig.useSymbols = isChecked
|
||||||
}
|
}
|
||||||
|
@ -4,40 +4,31 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import android.widget.TextView
|
import android.view.LayoutInflater
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import pl.szczodrzynski.edziennik.R
|
||||||
import com.google.android.material.textfield.TextInputEditText
|
import pl.szczodrzynski.edziennik.databinding.DialogEditTextBinding
|
||||||
import com.google.android.material.textfield.TextInputLayout
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class BellSyncConfigDialog(
|
class BellSyncConfigDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onChangeListener: (() -> Unit)? = null,
|
private val onChangeListener: (() -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogEditTextBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "BellSyncConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "BellSyncConfigDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.bell_sync_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogEditTextBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
// local variables go here
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNeutralButtonText() = R.string.reset
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
private fun parse(input: String): Pair<Time, Int>? {
|
private fun parse(input: String): Pair<Time, Int>? {
|
||||||
if (input.length < 8) {
|
if (input.length < 8) {
|
||||||
@ -56,51 +47,28 @@ class BellSyncConfigDialog(
|
|||||||
return time to multiplier
|
return time to multiplier
|
||||||
}
|
}
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
b.title.setText(R.string.bell_sync_adjust_content)
|
||||||
return@run
|
b.text1.hint = "±H:MM:SS"
|
||||||
onShowListener?.invoke(TAG)
|
b.text1.setText(app.config.timetable.bellSyncDiff?.let {
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.bell_sync_title)
|
|
||||||
.setView(R.layout.dialog_edit_text)
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setNeutralButton(R.string.reset) { _, _ ->
|
|
||||||
app.config.timetable.bellSyncDiff = null
|
|
||||||
app.config.timetable.bellSyncMultiplier = 0
|
|
||||||
onChangeListener?.invoke()
|
|
||||||
}
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
val message = dialog.findViewById<TextView>(android.R.id.title)
|
|
||||||
val editText = dialog.findViewById<TextInputEditText>(android.R.id.text1)
|
|
||||||
val textLayout = dialog.findViewById<TextInputLayout>(R.id.text_input_layout)
|
|
||||||
|
|
||||||
message?.setText(R.string.bell_sync_adjust_content)
|
|
||||||
editText?.hint = "±H:MM:SS"
|
|
||||||
editText?.setText(app.config.timetable.bellSyncDiff?.let {
|
|
||||||
(if (app.config.timetable.bellSyncMultiplier == -1) "-" else "+") + it.stringHMS
|
(if (app.config.timetable.bellSyncMultiplier == -1) "-" else "+") + it.stringHMS
|
||||||
} ?: "+0:00:00")
|
} ?: "+0:00:00")
|
||||||
editText?.addTextChangedListener { text ->
|
b.text1.addTextChangedListener { text ->
|
||||||
val input = text?.toString()
|
val input = text?.toString()
|
||||||
textLayout?.error =
|
b.textInputLayout.error =
|
||||||
if (input != null && parse(input) == null)
|
if (input != null && parse(input) == null)
|
||||||
activity.getString(R.string.bell_sync_adjust_error)
|
activity.getString(R.string.bell_sync_adjust_error)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick {
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
val input = editText?.text?.toString() ?: return@onClick
|
val input = b.text1.text?.toString() ?: return NO_DISMISS
|
||||||
val parsed = parse(input)
|
val parsed = parse(input)
|
||||||
if (parsed == null) {
|
if (parsed == null) {
|
||||||
Toast.makeText(activity, R.string.bell_sync_adjust_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, R.string.bell_sync_adjust_error, Toast.LENGTH_SHORT).show()
|
||||||
return@onClick
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
|
|
||||||
val (time, multiplier) = parsed
|
val (time, multiplier) = parsed
|
||||||
@ -112,7 +80,13 @@ class BellSyncConfigDialog(
|
|||||||
app.config.timetable.bellSyncMultiplier = multiplier
|
app.config.timetable.bellSyncMultiplier = multiplier
|
||||||
|
|
||||||
onChangeListener?.invoke()
|
onChangeListener?.invoke()
|
||||||
dialog.dismiss()
|
return DISMISS
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
|
app.config.timetable.bellSyncDiff = null
|
||||||
|
app.config.timetable.bellSyncMultiplier = 0
|
||||||
|
onChangeListener?.invoke()
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,18 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import it.sephiroth.android.library.numberpicker.doOnStopTrackingTouch
|
import it.sephiroth.android.library.numberpicker.doOnStopTrackingTouch
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogConfigGradesBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogConfigGradesBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.join
|
import pl.szczodrzynski.edziennik.ext.join
|
||||||
import pl.szczodrzynski.edziennik.ext.onChange
|
import pl.szczodrzynski.edziennik.ext.onChange
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import pl.szczodrzynski.edziennik.ext.setOnSelectedListener
|
import pl.szczodrzynski.edziennik.ext.setOnSelectedListener
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_DEFAULT
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_DEFAULT
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||||
@ -25,47 +26,29 @@ import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_
|
|||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_SEM
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_1_SEM_2_SEM
|
||||||
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class GradesConfigDialog(
|
class GradesConfigDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val reloadOnDismiss: Boolean = true,
|
reloadOnDismiss: Boolean = true,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : ConfigDialog<DialogConfigGradesBinding>(
|
||||||
|
activity,
|
||||||
|
reloadOnDismiss,
|
||||||
|
onShowListener,
|
||||||
|
onDismissListener,
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
const val TAG = "GradesConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "GradesConfigDialog"
|
||||||
private val config by lazy { app.config.grades }
|
|
||||||
|
override fun getTitleRes() = R.string.menu_grades_config
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogConfigGradesBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
private val profileConfig by lazy { app.config.getFor(app.profileId).grades }
|
private val profileConfig by lazy { app.config.getFor(app.profileId).grades }
|
||||||
|
|
||||||
private lateinit var b: DialogConfigGradesBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
b = DialogConfigGradesBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.menu_grades_config)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
saveConfig()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
initView()
|
|
||||||
loadConfig()
|
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
private fun loadConfig() {
|
override suspend fun loadConfig() {
|
||||||
b.customPlusCheckBox.isChecked = profileConfig.plusValue != null
|
b.customPlusCheckBox.isChecked = profileConfig.plusValue != null
|
||||||
b.customPlusValue.isVisible = b.customPlusCheckBox.isChecked
|
b.customPlusValue.isVisible = b.customPlusCheckBox.isChecked
|
||||||
b.customMinusCheckBox.isChecked = profileConfig.minusValue != null
|
b.customMinusCheckBox.isChecked = profileConfig.minusValue != null
|
||||||
@ -95,21 +78,23 @@ class GradesConfigDialog(
|
|||||||
else -> null
|
else -> null
|
||||||
}?.isChecked = true
|
}?.isChecked = true
|
||||||
|
|
||||||
b.dontCountGrades.isChecked = profileConfig.dontCountEnabled && profileConfig.dontCountGrades.isNotEmpty()
|
b.dontCountGrades.isChecked =
|
||||||
|
profileConfig.dontCountEnabled && profileConfig.dontCountGrades.isNotEmpty()
|
||||||
b.hideImproved.isChecked = profileConfig.hideImproved
|
b.hideImproved.isChecked = profileConfig.hideImproved
|
||||||
b.averageWithoutWeight.isChecked = profileConfig.averageWithoutWeight
|
b.averageWithoutWeight.isChecked = profileConfig.averageWithoutWeight
|
||||||
|
|
||||||
if (profileConfig.dontCountGrades.isEmpty()) {
|
if (profileConfig.dontCountGrades.isEmpty()) {
|
||||||
b.dontCountGradesText.setText("nb, 0, bz, bd")
|
b.dontCountGradesText.setText("nb, 0, bz, bd")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
b.dontCountGradesText.setText(profileConfig.dontCountGrades.join(", "))
|
b.dontCountGradesText.setText(profileConfig.dontCountGrades.join(", "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveConfig() {
|
override suspend fun saveConfig() {
|
||||||
profileConfig.plusValue = if (b.customPlusCheckBox.isChecked) b.customPlusValue.progress else null
|
profileConfig.plusValue =
|
||||||
profileConfig.minusValue = if (b.customMinusCheckBox.isChecked) b.customMinusValue.progress else null
|
if (b.customPlusCheckBox.isChecked) b.customPlusValue.progress else null
|
||||||
|
profileConfig.minusValue =
|
||||||
|
if (b.customMinusCheckBox.isChecked) b.customMinusValue.progress else null
|
||||||
|
|
||||||
b.dontCountGradesText.setText(
|
b.dontCountGradesText.setText(
|
||||||
b.dontCountGradesText
|
b.dontCountGradesText
|
||||||
@ -125,7 +110,7 @@ class GradesConfigDialog(
|
|||||||
?: listOf()
|
?: listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
override fun initView() {
|
||||||
b.customPlusCheckBox.onChange { _, isChecked ->
|
b.customPlusCheckBox.onChange { _, isChecked ->
|
||||||
b.customPlusValue.isVisible = isChecked
|
b.customPlusValue.isVisible = isChecked
|
||||||
}
|
}
|
||||||
@ -145,17 +130,31 @@ class GradesConfigDialog(
|
|||||||
b.sortGradesByDateRadio.setOnSelectedListener { config.orderBy = ORDER_BY_DATE_DESC }
|
b.sortGradesByDateRadio.setOnSelectedListener { config.orderBy = ORDER_BY_DATE_DESC }
|
||||||
b.sortGradesBySubjectRadio.setOnSelectedListener { config.orderBy = ORDER_BY_SUBJECT_ASC }
|
b.sortGradesBySubjectRadio.setOnSelectedListener { config.orderBy = ORDER_BY_SUBJECT_ASC }
|
||||||
|
|
||||||
b.gradeColorFromERegister.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_DEFAULT }
|
b.gradeColorFromERegister.setOnSelectedListener {
|
||||||
|
profileConfig.colorMode = COLOR_MODE_DEFAULT
|
||||||
|
}
|
||||||
b.gradeColorByValue.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_WEIGHTED }
|
b.gradeColorByValue.setOnSelectedListener { profileConfig.colorMode = COLOR_MODE_WEIGHTED }
|
||||||
|
|
||||||
b.gradeAverageMode4.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_ALL_GRADES }
|
b.gradeAverageMode4.setOnSelectedListener {
|
||||||
b.gradeAverageMode0.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_AVG_2_AVG }
|
profileConfig.yearAverageMode = YEAR_ALL_GRADES
|
||||||
b.gradeAverageMode1.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_SEM_2_AVG }
|
}
|
||||||
b.gradeAverageMode2.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_AVG_2_SEM }
|
b.gradeAverageMode0.setOnSelectedListener {
|
||||||
b.gradeAverageMode3.setOnSelectedListener { profileConfig.yearAverageMode = YEAR_1_SEM_2_SEM }
|
profileConfig.yearAverageMode = YEAR_1_AVG_2_AVG
|
||||||
|
}
|
||||||
|
b.gradeAverageMode1.setOnSelectedListener {
|
||||||
|
profileConfig.yearAverageMode = YEAR_1_SEM_2_AVG
|
||||||
|
}
|
||||||
|
b.gradeAverageMode2.setOnSelectedListener {
|
||||||
|
profileConfig.yearAverageMode = YEAR_1_AVG_2_SEM
|
||||||
|
}
|
||||||
|
b.gradeAverageMode3.setOnSelectedListener {
|
||||||
|
profileConfig.yearAverageMode = YEAR_1_SEM_2_SEM
|
||||||
|
}
|
||||||
|
|
||||||
b.hideImproved.onChange { _, isChecked -> profileConfig.hideImproved = isChecked }
|
b.hideImproved.onChange { _, isChecked -> profileConfig.hideImproved = isChecked }
|
||||||
b.averageWithoutWeight.onChange { _, isChecked -> profileConfig.averageWithoutWeight = isChecked }
|
b.averageWithoutWeight.onChange { _, isChecked ->
|
||||||
|
profileConfig.averageWithoutWeight = isChecked
|
||||||
|
}
|
||||||
|
|
||||||
b.averageWithoutWeightHelp.onClick {
|
b.averageWithoutWeightHelp.onClick {
|
||||||
MaterialAlertDialogBuilder(activity)
|
MaterialAlertDialogBuilder(activity)
|
||||||
|
@ -4,59 +4,42 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.MessagesConfigDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.MessagesConfigDialogBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||||
|
|
||||||
class MessagesConfigDialog(
|
class MessagesConfigDialog(
|
||||||
private val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val reloadOnDismiss: Boolean = true,
|
reloadOnDismiss: Boolean = true,
|
||||||
private val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
private val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
|
) : ConfigDialog<MessagesConfigDialogBinding>(
|
||||||
|
activity,
|
||||||
|
reloadOnDismiss,
|
||||||
|
onShowListener,
|
||||||
|
onDismissListener,
|
||||||
) {
|
) {
|
||||||
companion object {
|
|
||||||
const val TAG = "MessagesConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
override val TAG = "MessagesConfigDialog"
|
||||||
private val config by lazy { app.config.ui }
|
|
||||||
private val profileConfig by lazy { app.config.forProfile().ui }
|
|
||||||
|
|
||||||
private lateinit var b: MessagesConfigDialogBinding
|
override fun getTitleRes() = R.string.menu_messages_config
|
||||||
private lateinit var dialog: AlertDialog
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
MessagesConfigDialogBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
init { run {
|
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
b = MessagesConfigDialogBinding.inflate(activity.layoutInflater)
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.menu_messages_config)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
saveConfig()
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
|
||||||
}
|
|
||||||
.create()
|
|
||||||
loadConfig()
|
|
||||||
dialog.show()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun loadConfig() {
|
override suspend fun loadConfig() {
|
||||||
b.config = profileConfig
|
b.config = profileConfig
|
||||||
|
|
||||||
b.greetingText.setText(
|
b.greetingText.setText(
|
||||||
profileConfig.messagesGreetingText ?: "\n\nZ poważaniem\n${app.profile.accountOwnerName}"
|
profileConfig.messagesGreetingText
|
||||||
|
?: "\n\nZ poważaniem\n${app.profile.accountOwnerName}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveConfig() {
|
override suspend fun saveConfig() {
|
||||||
val greetingText = b.greetingText.text?.toString()?.trim()
|
val greetingText = b.greetingText.text?.toString()?.trim()
|
||||||
if (greetingText.isNullOrEmpty())
|
if (greetingText.isNullOrEmpty())
|
||||||
profileConfig.messagesGreetingText = null
|
profileConfig.messagesGreetingText = null
|
||||||
|
@ -4,13 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
||||||
@ -24,73 +18,45 @@ import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_NOTIFICATIO
|
|||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_SETTINGS
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_SETTINGS
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
|
|
||||||
class MiniMenuConfigDialog(
|
class MiniMenuConfigDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "MiniMenuConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "BellSyncTimeChooseDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.settings_theme_mini_drawer_buttons_dialog_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getMessageRes() = R.string.settings_theme_mini_drawer_buttons_dialog_text
|
||||||
get() = job + Dispatchers.Main
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
// local variables go here
|
override fun getMultiChoiceItems(): Map<CharSequence, Any> = mapOf(
|
||||||
|
R.string.menu_home_page to DRAWER_ITEM_HOME,
|
||||||
|
R.string.menu_timetable to DRAWER_ITEM_TIMETABLE,
|
||||||
|
R.string.menu_agenda to DRAWER_ITEM_AGENDA,
|
||||||
|
R.string.menu_grades to DRAWER_ITEM_GRADES,
|
||||||
|
R.string.menu_messages to DRAWER_ITEM_MESSAGES,
|
||||||
|
R.string.menu_homework to DRAWER_ITEM_HOMEWORK,
|
||||||
|
R.string.menu_notices to DRAWER_ITEM_BEHAVIOUR,
|
||||||
|
R.string.menu_attendance to DRAWER_ITEM_ATTENDANCE,
|
||||||
|
R.string.menu_announcements to DRAWER_ITEM_ANNOUNCEMENTS,
|
||||||
|
R.string.menu_notifications to DRAWER_ITEM_NOTIFICATIONS,
|
||||||
|
R.string.menu_settings to DRAWER_ITEM_SETTINGS,
|
||||||
|
).mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
|
||||||
init { run {
|
override fun getDefaultSelectedItems() = app.config.ui.miniMenuButtons.toSet()
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
val buttons = mapOf(
|
override suspend fun onShow() = Unit
|
||||||
DRAWER_ITEM_HOME to R.string.menu_home_page,
|
|
||||||
DRAWER_ITEM_TIMETABLE to R.string.menu_timetable,
|
|
||||||
DRAWER_ITEM_AGENDA to R.string.menu_agenda,
|
|
||||||
DRAWER_ITEM_GRADES to R.string.menu_grades,
|
|
||||||
DRAWER_ITEM_MESSAGES to R.string.menu_messages,
|
|
||||||
DRAWER_ITEM_HOMEWORK to R.string.menu_homework,
|
|
||||||
DRAWER_ITEM_BEHAVIOUR to R.string.menu_notices,
|
|
||||||
DRAWER_ITEM_ATTENDANCE to R.string.menu_attendance,
|
|
||||||
DRAWER_ITEM_ANNOUNCEMENTS to R.string.menu_announcements,
|
|
||||||
DRAWER_ITEM_NOTIFICATIONS to R.string.menu_notifications,
|
|
||||||
DRAWER_ITEM_SETTINGS to R.string.menu_settings
|
|
||||||
)
|
|
||||||
val miniMenuButtons = app.config.ui.miniMenuButtons
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.settings_theme_mini_drawer_buttons_dialog_title)
|
|
||||||
//.setMessage(R.string.settings_theme_mini_drawer_buttons_dialog_text)
|
|
||||||
.setMultiChoiceItems(
|
|
||||||
buttons.map { activity.getString(it.value) }.toTypedArray(),
|
|
||||||
buttons.map { it.key in miniMenuButtons }.toBooleanArray(),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
|
||||||
app.config.ui.miniMenuButtons =
|
|
||||||
buttons.keys.mapIndexedNotNull { index, id ->
|
|
||||||
if (dialog.listView.checkedItemPositions[index])
|
|
||||||
id
|
|
||||||
else
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
app.config.ui.miniMenuButtons = getMultiSelection().filterIsInstance<Int>()
|
||||||
if (activity is MainActivity) {
|
if (activity is MainActivity) {
|
||||||
activity.setDrawerItems()
|
activity.setDrawerItems()
|
||||||
activity.drawer.updateBadges()
|
activity.drawer.updateBadges()
|
||||||
}
|
}
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,96 +4,71 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
// TODO refactor dialog to allow configuring other profiles
|
|
||||||
// than the selected one in UI
|
|
||||||
class NotificationFilterDialog(
|
class NotificationFilterDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "NotificationFilterDialog"
|
override val TAG = "NotificationFilterDialog"
|
||||||
private val notificationTypes = listOf(
|
|
||||||
Notification.TYPE_TIMETABLE_LESSON_CHANGE to R.string.notification_type_timetable_lesson_change,
|
override fun getTitleRes() = R.string.dialog_notification_filter_title
|
||||||
Notification.TYPE_NEW_GRADE to R.string.notification_type_new_grade,
|
override fun getMessageRes() = R.string.dialog_notification_filter_text
|
||||||
Notification.TYPE_NEW_EVENT to R.string.notification_type_new_event,
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
Notification.TYPE_NEW_HOMEWORK to R.string.notification_type_new_homework,
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
Notification.TYPE_NEW_MESSAGE to R.string.notification_type_new_message,
|
|
||||||
Notification.TYPE_LUCKY_NUMBER to R.string.notification_type_lucky_number,
|
override fun getMultiChoiceItems(): Map<CharSequence, Any> {
|
||||||
Notification.TYPE_NEW_NOTICE to R.string.notification_type_notice,
|
notificationTypes = mapOf(
|
||||||
Notification.TYPE_NEW_ATTENDANCE to R.string.notification_type_attendance,
|
R.string.notification_type_timetable_lesson_change to Notification.TYPE_TIMETABLE_LESSON_CHANGE,
|
||||||
Notification.TYPE_NEW_ANNOUNCEMENT to R.string.notification_type_new_announcement,
|
R.string.notification_type_new_grade to Notification.TYPE_NEW_GRADE,
|
||||||
Notification.TYPE_NEW_SHARED_EVENT to R.string.notification_type_new_shared_event,
|
R.string.notification_type_new_event to Notification.TYPE_NEW_EVENT,
|
||||||
Notification.TYPE_NEW_SHARED_HOMEWORK to R.string.notification_type_new_shared_homework,
|
R.string.notification_type_new_homework to Notification.TYPE_NEW_HOMEWORK,
|
||||||
Notification.TYPE_REMOVED_SHARED_EVENT to R.string.notification_type_removed_shared_event,
|
R.string.notification_type_new_message to Notification.TYPE_NEW_MESSAGE,
|
||||||
Notification.TYPE_TEACHER_ABSENCE to R.string.notification_type_new_teacher_absence
|
R.string.notification_type_lucky_number to Notification.TYPE_LUCKY_NUMBER,
|
||||||
)
|
R.string.notification_type_notice to Notification.TYPE_NEW_NOTICE,
|
||||||
|
R.string.notification_type_attendance to Notification.TYPE_NEW_ATTENDANCE,
|
||||||
|
R.string.notification_type_new_announcement to Notification.TYPE_NEW_ANNOUNCEMENT,
|
||||||
|
R.string.notification_type_new_shared_event to Notification.TYPE_NEW_SHARED_EVENT,
|
||||||
|
R.string.notification_type_new_shared_homework to Notification.TYPE_NEW_SHARED_HOMEWORK,
|
||||||
|
R.string.notification_type_removed_shared_event to Notification.TYPE_REMOVED_SHARED_EVENT,
|
||||||
|
R.string.notification_type_new_teacher_absence to Notification.TYPE_TEACHER_ABSENCE,
|
||||||
|
).mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
return notificationTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var app: App
|
override fun getDefaultSelectedItems() =
|
||||||
private lateinit var dialog: AlertDialog
|
notificationTypes.values.subtract(app.config.forProfile().sync.notificationFilter)
|
||||||
|
|
||||||
private val job = Job()
|
override suspend fun onShow() = Unit
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private val notificationFilter = mutableListOf<Int>()
|
private lateinit var notificationTypes: Map<CharSequence, Int>
|
||||||
|
|
||||||
init { run {
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
val enabledTypes = getMultiSelection().filterIsInstance<Int>()
|
||||||
return@run
|
val disabledTypes = notificationTypes.values.subtract(enabledTypes).toList()
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
notificationFilter.clear()
|
if (disabledTypes.isNotEmpty()) {
|
||||||
notificationFilter += app.config.forProfile().sync.notificationFilter
|
|
||||||
val items = notificationTypes.map { app.getString(it.second) }.toTypedArray()
|
|
||||||
val checkedItems = notificationTypes.map { !notificationFilter.contains(it.first) }.toBooleanArray()
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.dialog_notification_filter_title)
|
|
||||||
//.setMessage(R.string.dialog_notification_filter_text)
|
|
||||||
.setMultiChoiceItems(items, checkedItems) { _, which, isChecked ->
|
|
||||||
val type = notificationTypes[which].first
|
|
||||||
notificationFilter.remove(type)
|
|
||||||
if (!isChecked)
|
|
||||||
notificationFilter += type
|
|
||||||
}
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.onClick {
|
|
||||||
if (notificationFilter.isEmpty()) {
|
|
||||||
app.config.forProfile().sync.notificationFilter = notificationFilter
|
|
||||||
dialog.dismiss()
|
|
||||||
return@onClick
|
|
||||||
}
|
|
||||||
// warn user when he tries to disable some notifications
|
// warn user when he tries to disable some notifications
|
||||||
MaterialAlertDialogBuilder(activity)
|
MaterialAlertDialogBuilder(activity)
|
||||||
.setTitle(R.string.are_you_sure)
|
.setTitle(R.string.are_you_sure)
|
||||||
.setMessage(R.string.notification_filter_warning)
|
.setMessage(R.string.notification_filter_warning)
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
.setPositiveButton(R.string.ok) { _, _ ->
|
||||||
app.config.forProfile().sync.notificationFilter = notificationFilter
|
app.config.forProfile().sync.notificationFilter = disabledTypes
|
||||||
dialog.dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
|
return NO_DISMISS
|
||||||
|
}
|
||||||
|
|
||||||
|
app.config.forProfile().sync.notificationFilter = disabledTypes
|
||||||
|
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -5,14 +5,10 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import com.google.android.material.color.MaterialColors
|
import com.google.android.material.color.MaterialColors
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.google.android.material.shape.MaterialShapeDrawable
|
import com.google.android.material.shape.MaterialShapeDrawable
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogProfileConfigBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogProfileConfigBinding
|
||||||
@ -20,54 +16,38 @@ import pl.szczodrzynski.edziennik.ext.dp
|
|||||||
import pl.szczodrzynski.edziennik.ext.onChange
|
import pl.szczodrzynski.edziennik.ext.onChange
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.ProfileRemoveDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.ProfileRemoveDialog
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
|
|
||||||
class ProfileConfigDialog(
|
class ProfileConfigDialog(
|
||||||
val activity: MainActivity,
|
activity: MainActivity,
|
||||||
val profile: Profile,
|
private val profile: Profile,
|
||||||
val onProfileSaved: ((profile: Profile) -> Unit)? = null,
|
private val onProfileSaved: ((profile: Profile) -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogProfileConfigBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "ProfileConfigDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "ProfileConfigDialog"
|
||||||
private lateinit var b: DialogProfileConfigBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes(): Int? = null
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogProfileConfigBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
|
||||||
// local variables go here
|
|
||||||
private var profileChanged = false
|
private var profileChanged = false
|
||||||
private var profileRemoved = false
|
private var profileRemoved = false
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogProfileConfigBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
if (!profileRemoved && profileChanged) {
|
|
||||||
app.profileSave(profile)
|
|
||||||
onProfileSaved?.invoke(profile)
|
|
||||||
}
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
b.profile = profile
|
b.profile = profile
|
||||||
profile.applyImageTo(b.image)
|
profile.applyImageTo(b.image)
|
||||||
|
|
||||||
// I can't believe how simple it is to get the dialog's background color !!
|
// I can't believe how simple it is to get the dialog's background color !!
|
||||||
val shape = MaterialShapeDrawable(activity, null, R.attr.alertDialogStyle, R.style.MaterialAlertDialog_MaterialComponents)
|
val shape = MaterialShapeDrawable(
|
||||||
|
activity,
|
||||||
|
null,
|
||||||
|
R.attr.alertDialogStyle,
|
||||||
|
R.style.MaterialAlertDialog_MaterialComponents
|
||||||
|
)
|
||||||
val surface = MaterialColors.getColor(activity, R.attr.colorSurface, TAG)
|
val surface = MaterialColors.getColor(activity, R.attr.colorSurface, TAG)
|
||||||
shape.setCornerSize(18.dp.toFloat())
|
shape.setCornerSize(18.dp.toFloat())
|
||||||
shape.initializeElevationOverlay(activity)
|
shape.initializeElevationOverlay(activity)
|
||||||
@ -84,6 +64,8 @@ class ProfileConfigDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.imageButton.onClick {
|
b.imageButton.onClick {
|
||||||
|
if (activity !is MainActivity)
|
||||||
|
return@onClick
|
||||||
activity.requestHandler.requestProfileImage(profile) {
|
activity.requestHandler.requestProfileImage(profile) {
|
||||||
val profile = it as? Profile ?: return@requestProfileImage
|
val profile = it as? Profile ?: return@requestProfileImage
|
||||||
if (this@ProfileConfigDialog.profile == profile) {
|
if (this@ProfileConfigDialog.profile == profile) {
|
||||||
@ -98,7 +80,14 @@ class ProfileConfigDialog(
|
|||||||
ProfileRemoveDialog(activity, profile.id, profile.name) {
|
ProfileRemoveDialog(activity, profile.id, profile.name) {
|
||||||
profileRemoved = true
|
profileRemoved = true
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
|
}.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
if (!profileRemoved && profileChanged) {
|
||||||
|
app.profileSave(profile)
|
||||||
|
onProfileSaved?.invoke(profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,44 +4,28 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.ext.HOUR
|
import pl.szczodrzynski.edziennik.ext.HOUR
|
||||||
import pl.szczodrzynski.edziennik.ext.MINUTE
|
import pl.szczodrzynski.edziennik.ext.MINUTE
|
||||||
import pl.szczodrzynski.edziennik.ext.getSyncInterval
|
import pl.szczodrzynski.edziennik.ext.getSyncInterval
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
|
|
||||||
class SyncIntervalDialog(
|
class SyncIntervalDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onChangeListener: (() -> Unit)? = null,
|
private val onChangeListener: (() -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "SyncIntervalDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "SyncIntervalDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.settings_sync_sync_interval_dialog_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getMessageRes() = R.string.settings_sync_sync_interval_dialog_text
|
||||||
get() = job + Dispatchers.Main
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
// local variables go here
|
override fun getSingleChoiceItems(): Map<CharSequence, Any> = listOf(
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
val intervals = listOf(
|
|
||||||
30 * MINUTE,
|
30 * MINUTE,
|
||||||
45 * MINUTE,
|
45 * MINUTE,
|
||||||
60 * MINUTE,
|
60 * MINUTE,
|
||||||
@ -50,31 +34,17 @@ class SyncIntervalDialog(
|
|||||||
3 * HOUR,
|
3 * HOUR,
|
||||||
4 * HOUR,
|
4 * HOUR,
|
||||||
6 * HOUR,
|
6 * HOUR,
|
||||||
10 * HOUR
|
10 * HOUR,
|
||||||
)
|
).associateBy { activity.getSyncInterval(it.toInt()) }
|
||||||
val intervalNames = intervals.map {
|
|
||||||
activity.getSyncInterval(it.toInt())
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
override fun getDefaultSelectedItem() = app.config.sync.interval.toLong()
|
||||||
.setTitle(R.string.settings_sync_sync_interval_dialog_title)
|
|
||||||
//.setMessage(R.string.settings_sync_sync_interval_dialog_text)
|
|
||||||
.setSingleChoiceItems(
|
|
||||||
intervalNames.toTypedArray(),
|
|
||||||
intervals.indexOf(app.config.sync.interval.toLong()),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
|
||||||
val which = dialog.listView.checkedItemPosition
|
|
||||||
|
|
||||||
val interval = intervals[which]
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
val interval = getSingleSelection() as? Long ?: return DISMISS
|
||||||
app.config.sync.interval = interval.toInt()
|
app.config.sync.interval = interval.toInt()
|
||||||
onChangeListener?.invoke()
|
onChangeListener?.invoke()
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,62 +4,38 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes
|
import pl.szczodrzynski.edziennik.utils.Themes
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class ThemeChooserDialog(
|
class ThemeChooserDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "ThemeChooserDialog"
|
override val TAG = "ThemeChooserDialog"
|
||||||
|
|
||||||
|
override fun getTitleRes() = R.string.settings_theme_theme_text
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
|
override fun getSingleChoiceItems(): Map<CharSequence, Any> = Themes.themeList.associate {
|
||||||
|
activity.getString(it.name) to it.id
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var app: App
|
override fun getDefaultSelectedItem() = Themes.theme.id
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override suspend fun onShow() = Unit
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
// local variables go here
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
val themeId = getSingleSelection() as? Int ?: return DISMISS
|
||||||
init { run {
|
if (app.config.ui.theme != themeId) {
|
||||||
if (activity.isFinishing)
|
app.config.ui.theme = themeId
|
||||||
return@run
|
Themes.themeInt = themeId
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.settings_theme_theme_text)
|
|
||||||
.setSingleChoiceItems(
|
|
||||||
Themes.getThemeNames(activity).toTypedArray(),
|
|
||||||
Themes.themeIndex,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
|
||||||
val which = dialog.listView.checkedItemPosition
|
|
||||||
|
|
||||||
val theme = Themes.themeList[which]
|
|
||||||
if (app.config.ui.theme == theme.id)
|
|
||||||
return@setPositiveButton
|
|
||||||
app.config.ui.theme = theme.id
|
|
||||||
Themes.themeIndex = which
|
|
||||||
activity.recreate()
|
activity.recreate()
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
return DISMISS
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
}
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -6,89 +6,60 @@ package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
|||||||
|
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import coil.load
|
import coil.load
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.BuildConfig
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogRegisterUnavailableBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogRegisterUnavailableBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class RegisterUnavailableDialog(
|
class RegisterUnavailableDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val status: RegisterAvailabilityStatus,
|
private val status: RegisterAvailabilityStatus,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogRegisterUnavailableBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "RegisterUnavailableDialog"
|
override val TAG = "RegisterUnavailableDialog"
|
||||||
|
|
||||||
|
override fun getTitleRes(): Int? = null
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogRegisterUnavailableBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
|
||||||
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
|
if (!status.available && status.userMessage != null)
|
||||||
|
return true
|
||||||
|
|
||||||
|
if (status.minVersionCode <= BuildConfig.VERSION_CODE)
|
||||||
|
return false
|
||||||
|
|
||||||
|
val update = app.config.update
|
||||||
|
UpdateAvailableDialog(
|
||||||
|
activity = activity,
|
||||||
|
update = update,
|
||||||
|
mandatory = update != null && update.versionCode >= status.minVersionCode,
|
||||||
|
onShowListener = onShowListener,
|
||||||
|
onDismissListener = onDismissListener
|
||||||
|
).show()
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var app: App
|
override suspend fun onShow() {
|
||||||
private lateinit var dialog: AlertDialog
|
b.message = status.userMessage ?: return
|
||||||
|
b.text.movementMethod = LinkMovementMethod.getInstance()
|
||||||
|
|
||||||
private val job = Job()
|
if (status.userMessage.image != null) {
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
if (!status.available && status.userMessage != null) {
|
|
||||||
val b = DialogRegisterUnavailableBinding.inflate(LayoutInflater.from(activity), null, false)
|
|
||||||
b.message = status.userMessage
|
|
||||||
if (status.userMessage.image != null)
|
|
||||||
b.image.load(status.userMessage.image)
|
b.image.load(status.userMessage.image)
|
||||||
|
}
|
||||||
if (status.userMessage.url != null) {
|
if (status.userMessage.url != null) {
|
||||||
b.readMore.onClick {
|
b.readMore.onClick {
|
||||||
Utils.openUrl(activity, status.userMessage.url)
|
Utils.openUrl(activity, status.userMessage.url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.text.movementMethod = LinkMovementMethod.getInstance()
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
}
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
val update = app.config.update
|
|
||||||
if (status.minVersionCode > BuildConfig.VERSION_CODE) {
|
|
||||||
if (update != null && update.versionCode >= status.minVersionCode) {
|
|
||||||
UpdateAvailableDialog(activity, update, true, onShowListener, onDismissListener)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// this *should* never happen
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.update_available_title)
|
|
||||||
.setMessage(R.string.update_available_fallback)
|
|
||||||
.setPositiveButton(R.string.update_available_button) { dialog, _ ->
|
|
||||||
Utils.openGooglePlay(activity)
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.setCancelable(false)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,48 +4,24 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
|
|
||||||
class ServerMessageDialog(
|
class ServerMessageDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val title: String,
|
private val titleText: String,
|
||||||
val message: CharSequence,
|
private val messageText: CharSequence,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "ServerMessageDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "ServerMessageDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitle() = titleText
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getTitleRes(): Int? = null
|
||||||
get() = job + Dispatchers.Main
|
override fun getMessage() = messageText
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() = Unit
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(title)
|
|
||||||
.setMessage(message)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,113 +4,93 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class SyncViewListDialog(
|
class SyncViewListDialog(
|
||||||
val activity: MainActivity,
|
activity: MainActivity,
|
||||||
val currentViewId: Int? = null
|
private val currentViewId: Int,
|
||||||
) : CoroutineScope {
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
companion object {
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
private const val TAG = "SyncViewListDialog"
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
|
override val TAG = "SyncViewListDialog"
|
||||||
|
|
||||||
|
override fun getTitleRes() = R.string.dialog_sync_view_list_title
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNeutralButtonText() = R.string.sync_feature_all
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
|
override fun getMultiChoiceItems(): Map<CharSequence, Any> {
|
||||||
|
items = mapOf(
|
||||||
|
R.string.menu_timetable to DRAWER_ITEM_TIMETABLE,
|
||||||
|
R.string.menu_agenda to DRAWER_ITEM_AGENDA,
|
||||||
|
R.string.menu_grades to DRAWER_ITEM_GRADES,
|
||||||
|
R.string.menu_homework to DRAWER_ITEM_HOMEWORK,
|
||||||
|
R.string.menu_notices to DRAWER_ITEM_BEHAVIOUR,
|
||||||
|
R.string.menu_attendance to DRAWER_ITEM_ATTENDANCE,
|
||||||
|
R.string.title_messages_inbox_single to (DRAWER_ITEM_MESSAGES to 0),
|
||||||
|
R.string.title_messages_sent_single to (DRAWER_ITEM_MESSAGES to 1),
|
||||||
|
R.string.menu_announcements to DRAWER_ITEM_ANNOUNCEMENTS,
|
||||||
|
).mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var job: Job
|
override fun getDefaultSelectedItems(): Set<Any> {
|
||||||
override val coroutineContext: CoroutineContext
|
val everything = currentViewId == DRAWER_ITEM_HOME
|
||||||
get() = job + Dispatchers.Main
|
return when {
|
||||||
|
everything -> items.values.toSet()
|
||||||
private val app by lazy { activity.application as App }
|
currentViewId == DRAWER_ITEM_MESSAGES -> when (MessagesFragment.pageSelection) {
|
||||||
private lateinit var b: DialogLessonDetailsBinding
|
1 -> setOf(DRAWER_ITEM_MESSAGES to 1)
|
||||||
private lateinit var dialog: AlertDialog
|
else -> setOf(DRAWER_ITEM_MESSAGES to 0)
|
||||||
|
|
||||||
init { run {
|
|
||||||
job = Job()
|
|
||||||
|
|
||||||
val viewIds = arrayOf(
|
|
||||||
MainActivity.DRAWER_ITEM_TIMETABLE,
|
|
||||||
MainActivity.DRAWER_ITEM_AGENDA,
|
|
||||||
MainActivity.DRAWER_ITEM_GRADES,
|
|
||||||
MainActivity.DRAWER_ITEM_HOMEWORK,
|
|
||||||
MainActivity.DRAWER_ITEM_BEHAVIOUR,
|
|
||||||
MainActivity.DRAWER_ITEM_ATTENDANCE,
|
|
||||||
MainActivity.DRAWER_ITEM_MESSAGES,
|
|
||||||
MainActivity.DRAWER_ITEM_MESSAGES,
|
|
||||||
MainActivity.DRAWER_ITEM_ANNOUNCEMENTS
|
|
||||||
)
|
|
||||||
|
|
||||||
val items = arrayOf<String>(
|
|
||||||
app.getString(R.string.menu_timetable),
|
|
||||||
app.getString(R.string.menu_agenda),
|
|
||||||
app.getString(R.string.menu_grades),
|
|
||||||
app.getString(R.string.menu_homework),
|
|
||||||
app.getString(R.string.menu_notices),
|
|
||||||
app.getString(R.string.menu_attendance),
|
|
||||||
app.getString(R.string.title_messages_inbox_single),
|
|
||||||
app.getString(R.string.title_messages_sent_single),
|
|
||||||
app.getString(R.string.menu_announcements)
|
|
||||||
)
|
|
||||||
|
|
||||||
val everything = currentViewId == MainActivity.DRAWER_ITEM_HOME
|
|
||||||
val checkedItems = booleanArrayOf(
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_TIMETABLE,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_AGENDA,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_GRADES,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_HOMEWORK,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_BEHAVIOUR,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_ATTENDANCE,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_MESSAGES && MessagesFragment.pageSelection != 1,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_MESSAGES && MessagesFragment.pageSelection == 1,
|
|
||||||
everything || currentViewId == MainActivity.DRAWER_ITEM_ANNOUNCEMENTS
|
|
||||||
)
|
|
||||||
val userChooses = checkedItems.toMutableList()
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.dialog_sync_view_list_title)
|
|
||||||
.setMultiChoiceItems(items, checkedItems) { _, which, isChecked ->
|
|
||||||
userChooses[which] = isChecked
|
|
||||||
}
|
}
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
else -> setOf(currentViewId)
|
||||||
dialog.dismiss()
|
|
||||||
|
|
||||||
val selectedViewIds = userChooses.mapIndexed { index, it ->
|
|
||||||
if (it)
|
|
||||||
viewIds[index] to when (index) {
|
|
||||||
7 -> 1
|
|
||||||
else -> 0
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
null
|
|
||||||
}.let {
|
|
||||||
listOfNotNull(*it.toTypedArray())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedViewIds.isNotEmpty()) {
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
|
private lateinit var items: Map<CharSequence, Any>
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
val selected = getMultiSelection().mapNotNull {
|
||||||
|
when (it) {
|
||||||
|
is Int -> it to 0
|
||||||
|
is Pair<*, *> -> it as Pair<Int, Int>
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected.isEmpty())
|
||||||
|
return DISMISS
|
||||||
|
|
||||||
|
if (activity is MainActivity)
|
||||||
activity.swipeRefreshLayout.isRefreshing = true
|
activity.swipeRefreshLayout.isRefreshing = true
|
||||||
EdziennikTask.syncProfile(
|
EdziennikTask.syncProfile(
|
||||||
App.profileId,
|
App.profileId,
|
||||||
selectedViewIds
|
selected
|
||||||
).enqueue(activity)
|
).enqueue(activity)
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.setNeutralButton(R.string.sync_feature_all) { _, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
|
|
||||||
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
|
if (activity is MainActivity)
|
||||||
activity.swipeRefreshLayout.isRefreshing = true
|
activity.swipeRefreshLayout.isRefreshing = true
|
||||||
EdziennikTask.syncProfile(App.profileId).enqueue(activity)
|
EdziennikTask.syncProfile(App.profileId).enqueue(activity)
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel) { _, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -4,66 +4,54 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.ext.Intent
|
import pl.szczodrzynski.edziennik.ext.Intent
|
||||||
import pl.szczodrzynski.edziennik.ext.setMessage
|
|
||||||
import pl.szczodrzynski.edziennik.sync.UpdateDownloaderService
|
import pl.szczodrzynski.edziennik.sync.UpdateDownloaderService
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class UpdateAvailableDialog(
|
class UpdateAvailableDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val update: Update,
|
private val update: Update?,
|
||||||
val mandatory: Boolean = update.updateMandatory,
|
private val mandatory: Boolean = update?.updateMandatory ?: false,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "UpdateAvailableDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "UpdateAvailableDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = R.string.update_available_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getMessageFormat(): Pair<Int, List<CharSequence>> {
|
||||||
get() = job + Dispatchers.Main
|
if (update != null) {
|
||||||
|
return R.string.update_available_format to listOf(
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
if (update.versionCode <= BuildConfig.VERSION_CODE)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.update_available_title)
|
|
||||||
.setMessage(
|
|
||||||
R.string.update_available_format,
|
|
||||||
BuildConfig.VERSION_NAME,
|
BuildConfig.VERSION_NAME,
|
||||||
update.versionName,
|
update.versionName,
|
||||||
update.releaseNotes?.let { BetterHtml.fromHtml(activity, it) } ?: "---"
|
update.releaseNotes?.let { BetterHtml.fromHtml(activity, it) } ?: "---",
|
||||||
)
|
)
|
||||||
.setPositiveButton(R.string.update_available_button) { dialog, _ ->
|
}
|
||||||
|
return R.string.update_available_fallback to emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isCancelable() = !mandatory
|
||||||
|
override fun getPositiveButtonText() = R.string.update_available_button
|
||||||
|
override fun getNeutralButtonText() = if (mandatory) null else R.string.update_available_later
|
||||||
|
|
||||||
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
if (update == null)
|
||||||
|
Utils.openGooglePlay(activity)
|
||||||
|
else
|
||||||
activity.startService(Intent(app, UpdateDownloaderService::class.java))
|
activity.startService(Intent(app, UpdateDownloaderService::class.java))
|
||||||
dialog.dismiss()
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
.also {
|
|
||||||
if (!mandatory)
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
it.setNeutralButton(R.string.update_available_later, null)
|
// show only if app is older than available
|
||||||
|
return update == null || update.versionCode > BuildConfig.VERSION_CODE
|
||||||
}
|
}
|
||||||
.setCancelable(!mandatory)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -5,46 +5,32 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.error
|
package pl.szczodrzynski.edziennik.ui.error
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.withContext
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||||
import pl.szczodrzynski.edziennik.ext.*
|
import pl.szczodrzynski.edziennik.ext.*
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
|
|
||||||
class ErrorDetailsDialog(
|
class ErrorDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val errors: List<ApiError>,
|
private val errors: List<ApiError>,
|
||||||
val titleRes: Int = R.string.dialog_error_details_title,
|
private val titleRes: Int = R.string.dialog_error_details_title,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "ApiErrorDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "ErrorDetailsDialog"
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes() = titleRes
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getMessage() = errors.map {
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private val api by lazy { SzkolnyApi(activity.applicationContext as App) }
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
|
|
||||||
if (errors.isNotEmpty()) {
|
|
||||||
val message = errors.map {
|
|
||||||
listOf(
|
listOf(
|
||||||
it.getStringReason(activity).asBoldSpannable().asColoredSpannable(R.attr.colorOnBackground.resolveAttr(activity)),
|
it.getStringReason(activity)
|
||||||
|
.asBoldSpannable()
|
||||||
|
.asColoredSpannable(R.attr.colorOnBackground.resolveAttr(activity)),
|
||||||
activity.getString(R.string.error_unknown_format, it.errorCode, it.tag),
|
activity.getString(R.string.error_unknown_format, it.errorCode, it.tag),
|
||||||
if (App.devMode)
|
if (App.devMode)
|
||||||
it.throwable?.stackTraceString ?: it.throwable?.localizedMessage
|
it.throwable?.stackTraceString ?: it.throwable?.localizedMessage
|
||||||
@ -53,30 +39,30 @@ class ErrorDetailsDialog(
|
|||||||
).concat("\n")
|
).concat("\n")
|
||||||
}.concat("\n\n")
|
}.concat("\n\n")
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
override fun isCancelable() = false
|
||||||
.setTitle(titleRes)
|
override fun getPositiveButtonText() = R.string.close
|
||||||
.setMessage(message)
|
override fun getNeutralButtonText() = R.string.report
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
|
||||||
dialog.dismiss()
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
|
private val api by lazy { SzkolnyApi(activity.applicationContext as App) }
|
||||||
|
|
||||||
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
|
return errors.isNotEmpty()
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.report) { _, _ ->
|
|
||||||
launch {
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
api.runCatching({
|
api.runCatching({
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.Default) {
|
||||||
errorReport(errors.map { it.toReportableError(activity) })
|
errorReport(errors.map { it.toReportableError(activity) })
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
Toast.makeText(activity, activity.getString(R.string.crash_report_cannot_send) + it, Toast.LENGTH_LONG).show()
|
Toast.makeText(
|
||||||
}) ?: return@launch
|
activity,
|
||||||
|
activity.getString(R.string.crash_report_cannot_send) + it,
|
||||||
dialog.dismiss()
|
Toast.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
})
|
||||||
|
return DISMISS
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.setCancelable(false)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ class ErrorSnackbar(val activity: AppCompatActivity) : CoroutineScope {
|
|||||||
this.coordinator = coordinatorLayout
|
this.coordinator = coordinatorLayout
|
||||||
snackbar = Snackbar.make(coordinator, R.string.snackbar_error_text, Snackbar.LENGTH_INDEFINITE)
|
snackbar = Snackbar.make(coordinator, R.string.snackbar_error_text, Snackbar.LENGTH_INDEFINITE)
|
||||||
snackbar?.setAction(R.string.more) {
|
snackbar?.setAction(R.string.more) {
|
||||||
ErrorDetailsDialog(activity, errors)
|
ErrorDetailsDialog(activity, errors).show()
|
||||||
errors = mutableListOf()
|
errors = mutableListOf()
|
||||||
}
|
}
|
||||||
val bgColor = ColorUtils.compositeColors(
|
val bgColor = ColorUtils.compositeColors(
|
||||||
|
@ -8,6 +8,7 @@ import android.content.ActivityNotFoundException
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.provider.CalendarContract
|
import android.provider.CalendarContract
|
||||||
import android.provider.CalendarContract.Events
|
import android.provider.CalendarContract.Events
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
@ -25,74 +26,63 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
|||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogEventDetailsBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogEventDetailsBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.*
|
import pl.szczodrzynski.edziennik.ext.*
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
||||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
|
// TODO: 2021-10-19 rewrite to the new dialog style
|
||||||
class EventDetailsDialog(
|
class EventDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
// this event is observed for changes
|
// this event is observed for changes
|
||||||
var event: EventFull,
|
private var event: EventFull,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogEventDetailsBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "EventDetailsDialog"
|
override val TAG = "EventDetailsDialog"
|
||||||
}
|
|
||||||
|
override fun getTitleRes(): Int? = null
|
||||||
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogEventDetailsBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
override fun getNeutralButtonText() = if (event.addedManually) R.string.remove else null
|
||||||
|
|
||||||
private lateinit var app: App
|
|
||||||
private lateinit var b: DialogEventDetailsBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
private var removeEventDialog: AlertDialog? = null
|
private var removeEventDialog: AlertDialog? = null
|
||||||
private val eventShared = event.sharedBy != null
|
private val eventShared = event.sharedBy != null
|
||||||
private val eventOwn = event.sharedBy == "self"
|
private val eventOwn = event.sharedBy == "self"
|
||||||
private val manager
|
private val manager
|
||||||
get() = app.eventManager
|
get() = app.eventManager
|
||||||
|
|
||||||
private val job = Job()
|
|
||||||
override val coroutineContext: CoroutineContext
|
|
||||||
get() = job + Dispatchers.Main
|
|
||||||
|
|
||||||
private val api by lazy {
|
private val api by lazy {
|
||||||
SzkolnyApi(app)
|
SzkolnyApi(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var progressDialog: AlertDialog? = null
|
private var progressDialog: AlertDialog? = null
|
||||||
|
|
||||||
init { run {
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
EventBus.getDefault().register(this)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogEventDetailsBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.apply {
|
|
||||||
if (event.addedManually)
|
|
||||||
setNeutralButton(R.string.remove, null)
|
|
||||||
}
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
EventBus.getDefault().unregister(this@EventDetailsDialog)
|
|
||||||
progressDialog?.dismiss()
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.onClick {
|
|
||||||
showRemoveEventDialog()
|
showRemoveEventDialog()
|
||||||
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
|
EventBus.getDefault().register(this)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onShow() {
|
||||||
// watch the event for changes
|
// watch the event for changes
|
||||||
app.db.eventDao().getById(event.profileId, event.id).observe(activity) {
|
app.db.eventDao().getById(event.profileId, event.id).observe(activity) {
|
||||||
event = it ?: return@observe
|
event = it ?: return@observe
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
EventBus.getDefault().unregister(this@EventDetailsDialog)
|
||||||
|
progressDialog?.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
private fun update() {
|
private fun update() {
|
||||||
b.event = event
|
b.event = event
|
||||||
@ -185,7 +175,7 @@ class EventDetailsDialog(
|
|||||||
},
|
},
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
b.editButton.attachToastHint(R.string.hint_edit_event)
|
b.editButton.attachToastHint(R.string.hint_edit_event)
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.event
|
package pl.szczodrzynski.edziennik.ui.event
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
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 com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
@ -32,6 +32,7 @@ import pl.szczodrzynski.edziennik.data.db.full.LessonFull
|
|||||||
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
import pl.szczodrzynski.edziennik.databinding.DialogEventManualV2Binding
|
||||||
import pl.szczodrzynski.edziennik.ext.*
|
import pl.szczodrzynski.edziennik.ext.*
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.StyledTextDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.StyledTextDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.RegistrationConfigDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.RegistrationConfigDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
import pl.szczodrzynski.edziennik.ui.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
||||||
import pl.szczodrzynski.edziennik.utils.Anim
|
import pl.szczodrzynski.edziennik.utils.Anim
|
||||||
@ -40,32 +41,32 @@ import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.HtmlMode.SIM
|
|||||||
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.StylingConfigBase
|
import pl.szczodrzynski.edziennik.utils.managers.TextStylingManager.StylingConfigBase
|
||||||
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 kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
|
// TODO: 2021-10-19 rewrite to the new dialog style
|
||||||
class EventManualDialog(
|
class EventManualDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val profileId: Int,
|
private val profileId: Int,
|
||||||
val defaultLesson: LessonFull? = null,
|
private val defaultLesson: LessonFull? = null,
|
||||||
val defaultDate: Date? = null,
|
private val defaultDate: Date? = null,
|
||||||
val defaultTime: Time? = null,
|
private val defaultTime: Time? = null,
|
||||||
val defaultType: Long? = null,
|
private val defaultType: Long? = null,
|
||||||
val editingEvent: EventFull? = null,
|
private val editingEvent: EventFull? = null,
|
||||||
val onSaveListener: ((event: EventFull?) -> Unit)? = null,
|
private val onSaveListener: ((event: EventFull?) -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogEventManualV2Binding>(activity, onShowListener, onDismissListener) {
|
||||||
|
|
||||||
companion object {
|
override val TAG = "EventManualDialog"
|
||||||
private const val TAG = "EventManualDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val job: Job = Job()
|
override fun getTitleRes() = R.string.dialog_event_manual_title
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogEventManualV2Binding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun isCancelable() = false
|
||||||
|
override fun getPositiveButtonText() = R.string.save
|
||||||
|
override fun getNeutralButtonText() = if (editingEvent != null) R.string.remove else null
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
|
||||||
private lateinit var b: DialogEventManualV2Binding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
private lateinit var profile: Profile
|
private lateinit var profile: Profile
|
||||||
private lateinit var stylingConfig: StylingConfigBase
|
private lateinit var stylingConfig: StylingConfigBase
|
||||||
|
|
||||||
@ -86,46 +87,28 @@ class EventManualDialog(
|
|||||||
|
|
||||||
private var progressDialog: AlertDialog? = null
|
private var progressDialog: AlertDialog? = null
|
||||||
|
|
||||||
init { launch {
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
saveEvent()
|
||||||
return@launch
|
return NO_DISMISS
|
||||||
onShowListener?.invoke(TAG)
|
}
|
||||||
|
|
||||||
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
|
showRemoveEventDialog()
|
||||||
|
return NO_DISMISS
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun onBeforeShow(): Boolean {
|
||||||
EventBus.getDefault().register(this@EventManualDialog)
|
EventBus.getDefault().register(this@EventManualDialog)
|
||||||
b = DialogEventManualV2Binding.inflate(activity.layoutInflater)
|
return true
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.dialog_event_manual_title)
|
|
||||||
.setView(b.root)
|
|
||||||
.setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setPositiveButton(R.string.save, null)
|
|
||||||
.apply {
|
|
||||||
if (editingEvent != null) {
|
|
||||||
setNeutralButton(R.string.remove, null)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.setOnDismissListener {
|
override fun onDismiss() {
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
EventBus.getDefault().unregister(this@EventManualDialog)
|
EventBus.getDefault().unregister(this@EventManualDialog)
|
||||||
enqueuedWeekDialog?.dismiss()
|
enqueuedWeekDialog?.dismiss()
|
||||||
progressDialog?.dismiss()
|
progressDialog?.dismiss()
|
||||||
}
|
}
|
||||||
.setCancelable(false)
|
|
||||||
.create()
|
|
||||||
.apply {
|
|
||||||
setOnShowListener { dialog ->
|
|
||||||
val positiveButton = (dialog as AlertDialog).getButton(BUTTON_POSITIVE)
|
|
||||||
positiveButton?.setOnClickListener {
|
|
||||||
saveEvent()
|
|
||||||
}
|
|
||||||
|
|
||||||
val neutralButton = dialog.getButton(BUTTON_NEUTRAL)
|
|
||||||
neutralButton?.setOnClickListener {
|
|
||||||
showRemoveEventDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
override suspend fun onShow() {
|
||||||
b.shareSwitch.isChecked = editingShared
|
b.shareSwitch.isChecked = editingShared
|
||||||
b.shareSwitch.isEnabled = !editingShared || (editingShared && editingOwn)
|
b.shareSwitch.isEnabled = !editingShared || (editingShared && editingOwn)
|
||||||
|
|
||||||
@ -152,7 +135,7 @@ class EventManualDialog(
|
|||||||
},
|
},
|
||||||
onShowListener,
|
onShowListener,
|
||||||
onDismissListener
|
onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
stylingConfig = StylingConfigBase(editText = b.topic, htmlMode = SIMPLE)
|
stylingConfig = StylingConfigBase(editText = b.topic, htmlMode = SIMPLE)
|
||||||
@ -163,7 +146,7 @@ class EventManualDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
loadLists()
|
loadLists()
|
||||||
}}
|
}
|
||||||
|
|
||||||
private fun updateShareText(checked: Boolean = b.shareSwitch.isChecked) {
|
private fun updateShareText(checked: Boolean = b.shareSwitch.isChecked) {
|
||||||
b.shareDetails.visibility = if (checked || editingShared)
|
b.shareDetails.visibility = if (checked || editingShared)
|
||||||
@ -259,13 +242,13 @@ class EventManualDialog(
|
|||||||
progressDialog?.dismiss()
|
progressDialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLists() = launch {
|
private suspend fun loadLists() {
|
||||||
val profile = withContext(Dispatchers.Default) {
|
val profile = withContext(Dispatchers.Default) {
|
||||||
app.db.profileDao().getByIdNow(profileId)
|
app.db.profileDao().getByIdNow(profileId)
|
||||||
}
|
}
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
Toast.makeText(activity, R.string.event_manual_no_profile, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, R.string.event_manual_no_profile, Toast.LENGTH_SHORT).show()
|
||||||
return@launch
|
return
|
||||||
}
|
}
|
||||||
this@EventManualDialog.profile = profile
|
this@EventManualDialog.profile = profile
|
||||||
|
|
||||||
@ -611,7 +594,7 @@ class EventManualDialog(
|
|||||||
it.teamName = b.teamDropdown.getSelected()?.name
|
it.teamName = b.teamDropdown.getSelected()?.name
|
||||||
it.typeName = b.typeDropdown.getSelected()?.name
|
it.typeName = b.typeDropdown.getSelected()?.name
|
||||||
})
|
})
|
||||||
dialog.dismiss()
|
dismiss()
|
||||||
Toast.makeText(activity, R.string.saved, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, R.string.saved, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
private fun finishRemoving() {
|
private fun finishRemoving() {
|
||||||
@ -624,7 +607,7 @@ class EventManualDialog(
|
|||||||
|
|
||||||
removeEventDialog?.dismiss()
|
removeEventDialog?.dismiss()
|
||||||
onSaveListener?.invoke(null)
|
onSaveListener?.invoke(null)
|
||||||
dialog.dismiss()
|
dismiss()
|
||||||
Toast.makeText(activity, R.string.removed, Toast.LENGTH_SHORT).show()
|
Toast.makeText(activity, R.string.removed, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,56 +1,39 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.grades
|
package pl.szczodrzynski.edziennik.ui.grades
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.withContext
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog
|
||||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class GradeDetailsDialog(
|
class GradeDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val grade: GradeFull,
|
private val grade: GradeFull,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogGradeDetailsBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "GradeDetailsDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "GradeDetailsDialog"
|
||||||
private lateinit var b: DialogGradeDetailsBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes(): Int? = null
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogGradeDetailsBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
// local variables go here
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
|
||||||
init { run {
|
override suspend fun onShow() {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogGradeDetailsBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
val manager = app.gradesManager
|
val manager = app.gradesManager
|
||||||
|
|
||||||
val gradeColor = manager.getGradeColor(grade)
|
val gradeColor = manager.getGradeColor(grade)
|
||||||
@ -58,15 +41,23 @@ class GradeDetailsDialog(
|
|||||||
b.weightText = manager.getWeightString(app, grade)
|
b.weightText = manager.getWeightString(app, grade)
|
||||||
b.commentVisible = false
|
b.commentVisible = false
|
||||||
b.devMode = App.devMode
|
b.devMode = App.devMode
|
||||||
b.gradeName.setTextColor(if (ColorUtils.calculateLuminance(gradeColor) > 0.3) 0xaa000000.toInt() else 0xccffffff.toInt())
|
b.gradeName.setTextColor(
|
||||||
|
if (ColorUtils.calculateLuminance(gradeColor) > 0.3)
|
||||||
|
0xaa000000.toInt()
|
||||||
|
else
|
||||||
|
0xccffffff.toInt()
|
||||||
|
)
|
||||||
b.gradeName.background.setTintColor(gradeColor)
|
b.gradeName.background.setTintColor(gradeColor)
|
||||||
|
|
||||||
b.gradeValue = if (grade.weight == 0f || grade.value < 0f) -1f else manager.getGradeValue(grade)
|
b.gradeValue = if (grade.weight == 0f || grade.value < 0f)
|
||||||
|
-1f
|
||||||
|
else
|
||||||
|
manager.getGradeValue(grade)
|
||||||
|
|
||||||
b.customValueDivider.isVisible = manager.plusValue != null || manager.minusValue != null
|
b.customValueDivider.isVisible = manager.plusValue != null || manager.minusValue != null
|
||||||
b.customValueLayout.isVisible = b.customValueDivider.isVisible
|
b.customValueLayout.isVisible = b.customValueDivider.isVisible
|
||||||
b.customValueButton.onClick {
|
b.customValueButton.onClick {
|
||||||
GradesConfigDialog(activity, reloadOnDismiss = true)
|
GradesConfigDialog(activity, reloadOnDismiss = true).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
grade.teacherName?.let { name ->
|
grade.teacherName?.let { name ->
|
||||||
@ -77,24 +68,26 @@ class GradeDetailsDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
launch {
|
|
||||||
val historyList = withContext(Dispatchers.Default) {
|
val historyList = withContext(Dispatchers.Default) {
|
||||||
app.db.gradeDao().getByParentIdNow(App.profileId, grade.id)
|
app.db.gradeDao().getByParentIdNow(App.profileId, grade.id)
|
||||||
}
|
}
|
||||||
if (historyList.isEmpty()) {
|
if (historyList.isEmpty()) {
|
||||||
b.historyVisible = false
|
b.historyVisible = false
|
||||||
return@launch
|
return
|
||||||
}
|
}
|
||||||
b.historyVisible = true
|
b.historyVisible = true
|
||||||
//b.gradeHistoryNest.isNestedScrollingEnabled = false
|
//b.gradeHistoryNest.isNestedScrollingEnabled = false
|
||||||
|
|
||||||
b.gradeHistoryList.adapter = GradesAdapter(activity, {
|
b.gradeHistoryList.adapter = GradesAdapter(activity, {
|
||||||
GradeDetailsDialog(activity, it)
|
GradeDetailsDialog(activity, it).show()
|
||||||
}).also { it.items = historyList.toMutableList() }
|
}).also {
|
||||||
|
it.items = historyList.toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
b.gradeHistoryList.apply {
|
b.gradeHistoryList.apply {
|
||||||
setHasFixedSize(true)
|
setHasFixedSize(true)
|
||||||
layoutManager = LinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
|||||||
}})
|
}})
|
||||||
|
|
||||||
adapter.onGradeClick = {
|
adapter.onGradeClick = {
|
||||||
GradeDetailsDialog(activity, it)
|
GradeDetailsDialog(activity, it).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
adapter.onGradesEditorClick = { subject, semester ->
|
adapter.onGradesEditorClick = { subject, semester ->
|
||||||
@ -140,7 +140,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener(View.OnClickListener {
|
.withOnClickListener(View.OnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
GradesConfigDialog(activity, true, null, null)
|
GradesConfigDialog(activity, true, null, null).show()
|
||||||
}),
|
}),
|
||||||
BottomSheetSeparatorItem(true),
|
BottomSheetSeparatorItem(true),
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
|
@ -105,7 +105,7 @@ class StatsViewHolder(
|
|||||||
b.customValueDivider.isVisible = manager.dontCountEnabled || manager.plusValue != null || manager.minusValue != null
|
b.customValueDivider.isVisible = manager.dontCountEnabled || manager.plusValue != null || manager.minusValue != null
|
||||||
b.customValueLayout.isVisible = b.customValueDivider.isVisible
|
b.customValueLayout.isVisible = b.customValueDivider.isVisible
|
||||||
b.customValueButton.onClick {
|
b.customValueButton.onClick {
|
||||||
GradesConfigDialog(activity, reloadOnDismiss = true)
|
GradesConfigDialog(activity, reloadOnDismiss = true).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ class CounterActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
b.bellSync.onClick {
|
b.bellSync.onClick {
|
||||||
BellSyncTimeChooseDialog(activity = this@CounterActivity)
|
BellSyncTimeChooseDialog(activity = this@CounterActivity).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
app.config.timetable.bellSyncDiff?.let {
|
app.config.timetable.bellSyncDiff?.let {
|
||||||
|
@ -4,77 +4,66 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.home
|
package pl.szczodrzynski.edziennik.ui.home
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_EVENTS
|
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_EVENTS
|
||||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_GRADES
|
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_GRADES
|
||||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_LUCKY_NUMBER
|
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_LUCKY_NUMBER
|
||||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_TIMETABLE
|
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_TIMETABLE
|
||||||
import kotlin.collections.set
|
|
||||||
|
|
||||||
class HomeConfigDialog(
|
class HomeConfigDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
private val reloadOnDismiss: Boolean = true,
|
private val reloadOnDismiss: Boolean = true,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) {
|
) : BaseDialog(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
const val TAG = "HomeConfigDialog"
|
override val TAG = "HomeConfigDialog"
|
||||||
}
|
|
||||||
|
override fun getTitleRes() = R.string.home_configure_add_remove
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
|
override fun getMultiChoiceItems(): Map<CharSequence, Any> = mapOf(
|
||||||
|
R.string.card_type_lucky_number to CARD_LUCKY_NUMBER,
|
||||||
|
R.string.card_type_timetable to CARD_TIMETABLE,
|
||||||
|
R.string.card_type_grades to CARD_GRADES,
|
||||||
|
R.string.card_type_events to CARD_EVENTS,
|
||||||
|
).mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
|
||||||
|
override fun getDefaultSelectedItems() =
|
||||||
|
profileConfig.homeCards
|
||||||
|
.filter { it.profileId == App.profileId }
|
||||||
|
.map { it.cardId }
|
||||||
|
.toSet()
|
||||||
|
|
||||||
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
private val app by lazy { activity.application as App }
|
|
||||||
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
|
private val profileConfig by lazy { app.config.getFor(app.profileId).ui }
|
||||||
|
private var configChanged = false
|
||||||
|
|
||||||
private lateinit var dialog: AlertDialog
|
override suspend fun onPositiveClick(): Boolean {
|
||||||
|
val homeCards = profileConfig.homeCards.toMutableList()
|
||||||
init { run {
|
homeCards.removeAll { it.profileId == App.profileId }
|
||||||
if (activity.isFinishing)
|
homeCards += getMultiSelection().mapNotNull {
|
||||||
return@run
|
HomeCardModel(
|
||||||
onShowListener?.invoke(TAG)
|
profileId = App.profileId,
|
||||||
|
cardId = it as? Int ?: return@mapNotNull null
|
||||||
val ids = listOf(
|
|
||||||
CARD_LUCKY_NUMBER,
|
|
||||||
CARD_TIMETABLE,
|
|
||||||
CARD_GRADES,
|
|
||||||
CARD_EVENTS
|
|
||||||
)
|
)
|
||||||
val items = listOf(
|
|
||||||
app.getString(R.string.card_type_lucky_number),
|
|
||||||
app.getString(R.string.card_type_timetable),
|
|
||||||
app.getString(R.string.card_type_grades),
|
|
||||||
app.getString(R.string.card_type_events)
|
|
||||||
)
|
|
||||||
val checkedItems = ids.map { it to false }.toMap().toMutableMap()
|
|
||||||
|
|
||||||
val profileId = App.profileId
|
|
||||||
val homeCards = profileConfig.homeCards
|
|
||||||
.filter { it.profileId == profileId }
|
|
||||||
.toMutableList()
|
|
||||||
|
|
||||||
homeCards.forEach {
|
|
||||||
checkedItems[it.cardId] = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setTitle(R.string.home_configure_add_remove)
|
|
||||||
.setMultiChoiceItems(items.toTypedArray(), checkedItems.values.toBooleanArray()) { _, which, isChecked ->
|
|
||||||
if (isChecked) {
|
|
||||||
homeCards += HomeCardModel(profileId, ids[which])
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
homeCards.removeAll { it.profileId == profileId && it.cardId == ids[which] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.setPositiveButton(R.string.ok) { dialog, _ -> dialog.dismiss() }
|
|
||||||
.setOnDismissListener {
|
|
||||||
profileConfig.homeCards = homeCards
|
profileConfig.homeCards = homeCards
|
||||||
onDismissListener?.invoke(TAG)
|
return DISMISS
|
||||||
if (reloadOnDismiss) (activity as? MainActivity)?.reloadTarget()
|
}
|
||||||
|
|
||||||
|
override suspend fun onMultiSelectionChanged(items: Set<Any>) {
|
||||||
|
configChanged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDismiss() {
|
||||||
|
if (configChanged && reloadOnDismiss && activity is MainActivity)
|
||||||
|
activity.reloadTarget()
|
||||||
}
|
}
|
||||||
.show()
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ class HomeFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(Icon.cmd_card_bulleted_settings_outline)
|
.withIcon(Icon.cmd_card_bulleted_settings_outline)
|
||||||
.withOnClickListener(OnClickListener {
|
.withOnClickListener(OnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
HomeConfigDialog(activity, reloadOnDismiss = true)
|
HomeConfigDialog(activity, reloadOnDismiss = true).show()
|
||||||
}),
|
}),
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
.withTitle(R.string.menu_set_student_number)
|
.withTitle(R.string.menu_set_student_number)
|
||||||
@ -131,7 +131,7 @@ class HomeFragment : Fragment(), CoroutineScope {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
b.configureCards.onClick {
|
b.configureCards.onClick {
|
||||||
HomeConfigDialog(activity, reloadOnDismiss = true)
|
HomeConfigDialog(activity, reloadOnDismiss = true).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.scrollView.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, _: Int ->
|
b.scrollView.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, _: Int ->
|
||||||
|
@ -72,7 +72,7 @@ class HomeAvailabilityCard(
|
|||||||
if (status.userMessage.icon != null)
|
if (status.userMessage.icon != null)
|
||||||
b.homeAvailabilityIcon.load(status.userMessage.icon)
|
b.homeAvailabilityIcon.load(status.userMessage.icon)
|
||||||
onInfoClick = {
|
onInfoClick = {
|
||||||
RegisterUnavailableDialog(activity, status)
|
RegisterUnavailableDialog(activity, status).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// show "update available" when available OR version too old for the register
|
// show "update available" when available OR version too old for the register
|
||||||
@ -82,7 +82,7 @@ class HomeAvailabilityCard(
|
|||||||
b.homeAvailabilityUpdate.isVisible = true
|
b.homeAvailabilityUpdate.isVisible = true
|
||||||
b.homeAvailabilityIcon.setImageResource(R.drawable.ic_update)
|
b.homeAvailabilityIcon.setImageResource(R.drawable.ic_update)
|
||||||
onInfoClick = {
|
onInfoClick = {
|
||||||
UpdateAvailableDialog(activity, update)
|
UpdateAvailableDialog(activity, update).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -87,7 +87,7 @@ class HomeDebugCard(
|
|||||||
|
|
||||||
b.librusCaptchaButton.onClick {
|
b.librusCaptchaButton.onClick {
|
||||||
//app.startActivity(Intent(activity, LoginLibrusCaptchaActivity::class.java))
|
//app.startActivity(Intent(activity, LoginLibrusCaptchaActivity::class.java))
|
||||||
LibrusCaptchaDialog(activity, onSuccess = {}, onFailure = {})
|
LibrusCaptchaDialog(activity, onSuccess = {}, onFailure = {}).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.getLogs.onClick {
|
b.getLogs.onClick {
|
||||||
|
@ -70,14 +70,14 @@ class HomeEventsCard(
|
|||||||
EventDetailsDialog(
|
EventDetailsDialog(
|
||||||
activity,
|
activity,
|
||||||
it
|
it
|
||||||
)
|
).show()
|
||||||
},
|
},
|
||||||
onEventEditClick = {
|
onEventEditClick = {
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
it.profileId,
|
it.profileId,
|
||||||
editingEvent = it
|
editingEvent = it
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ class HomeTimetableCard(
|
|||||||
b.bellSync.setOnClickListener {
|
b.bellSync.setOnClickListener {
|
||||||
BellSyncTimeChooseDialog(
|
BellSyncTimeChooseDialog(
|
||||||
activity
|
activity
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
b.showCounter.setOnClickListener {
|
b.showCounter.setOnClickListener {
|
||||||
|
@ -65,7 +65,7 @@ class HomeworkFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||||
.withOnClickListener(View.OnClickListener {
|
.withOnClickListener(View.OnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK)
|
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK).show()
|
||||||
}),
|
}),
|
||||||
BottomSheetSeparatorItem(true),
|
BottomSheetSeparatorItem(true),
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
@ -108,7 +108,7 @@ class HomeworkFragment : Fragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setFabOnClickListener(View.OnClickListener {
|
setFabOnClickListener(View.OnClickListener {
|
||||||
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK)
|
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK).show()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,14 +68,14 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
|||||||
EventDetailsDialog(
|
EventDetailsDialog(
|
||||||
activity,
|
activity,
|
||||||
it
|
it
|
||||||
)
|
).show()
|
||||||
},
|
},
|
||||||
onEventEditClick = {
|
onEventEditClick = {
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
it.profileId,
|
it.profileId,
|
||||||
editingEvent = it
|
editingEvent = it
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ class LoginChooserFragment : Fragment(), CoroutineScope {
|
|||||||
|
|
||||||
return when (error.type) {
|
return when (error.type) {
|
||||||
Type.NOT_AVAILABLE -> {
|
Type.NOT_AVAILABLE -> {
|
||||||
RegisterUnavailableDialog(activity, error.status!!)
|
RegisterUnavailableDialog(activity, error.status!!).show()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
Type.API_ERROR -> {
|
Type.API_ERROR -> {
|
||||||
|
@ -141,7 +141,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener {
|
.withOnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
MessagesConfigDialog(activity, false, null, null)
|
MessagesConfigDialog(activity, false, null, null).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ class MessagesFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener {
|
.withOnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
MessagesConfigDialog(activity, false, null, null)
|
MessagesConfigDialog(activity, false, null, null).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class MessageFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||||
.withOnClickListener {
|
.withOnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
MessagesConfigDialog(activity, false, null, null)
|
MessagesConfigDialog(activity, false, null, null).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class SettingsAboutCard(util: SettingsUtil) : SettingsCard(util), CoroutineScope
|
|||||||
text = R.string.settings_about_changelog_text,
|
text = R.string.settings_about_changelog_text,
|
||||||
icon = CommunityMaterial.Icon3.cmd_radar
|
icon = CommunityMaterial.Icon3.cmd_radar
|
||||||
) {
|
) {
|
||||||
ChangelogDialog(activity)
|
ChangelogDialog(activity).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
|
@ -31,7 +31,7 @@ class SettingsProfileCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
card.items.remove(item)
|
card.items.remove(item)
|
||||||
card.items.add(index, getProfileItem())
|
card.items.add(index, getProfileItem())
|
||||||
util.refresh()
|
util.refresh()
|
||||||
})
|
}).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItems() = listOf(
|
override fun getItems() = listOf(
|
||||||
|
@ -59,28 +59,28 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
text = R.string.menu_agenda_config,
|
text = R.string.menu_agenda_config,
|
||||||
icon = CommunityMaterial.Icon.cmd_calendar_outline
|
icon = CommunityMaterial.Icon.cmd_calendar_outline
|
||||||
) {
|
) {
|
||||||
AgendaConfigDialog(activity, reloadOnDismiss = false)
|
AgendaConfigDialog(activity, reloadOnDismiss = false).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
text = R.string.menu_grades_config,
|
text = R.string.menu_grades_config,
|
||||||
icon = CommunityMaterial.Icon3.cmd_numeric_5_box_outline
|
icon = CommunityMaterial.Icon3.cmd_numeric_5_box_outline
|
||||||
) {
|
) {
|
||||||
GradesConfigDialog(activity, reloadOnDismiss = false)
|
GradesConfigDialog(activity, reloadOnDismiss = false).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
text = R.string.menu_messages_config,
|
text = R.string.menu_messages_config,
|
||||||
icon = CommunityMaterial.Icon.cmd_calendar_outline
|
icon = CommunityMaterial.Icon.cmd_calendar_outline
|
||||||
) {
|
) {
|
||||||
MessagesConfigDialog(activity, reloadOnDismiss = false)
|
MessagesConfigDialog(activity, reloadOnDismiss = false).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
text = R.string.menu_attendance_config,
|
text = R.string.menu_attendance_config,
|
||||||
icon = CommunityMaterial.Icon.cmd_calendar_remove_outline
|
icon = CommunityMaterial.Icon.cmd_calendar_remove_outline
|
||||||
) {
|
) {
|
||||||
AttendanceConfigDialog(activity, reloadOnDismiss = false)
|
AttendanceConfigDialog(activity, reloadOnDismiss = false).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createPropertyItem(
|
util.createPropertyItem(
|
||||||
@ -126,7 +126,7 @@ class SettingsRegisterCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
BellSyncConfigDialog(activity, onChangeListener = {
|
BellSyncConfigDialog(activity, onChangeListener = {
|
||||||
it.subText = getBellSync()
|
it.subText = getBellSync()
|
||||||
util.refresh()
|
util.refresh()
|
||||||
})
|
}).show()
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
it.subText = getBellSync()
|
it.subText = getBellSync()
|
||||||
|
@ -108,7 +108,7 @@ class SettingsSyncCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
item.onCheckedChangedAction.onCheckedChanged(item, true)
|
item.onCheckedChangedAction.onCheckedChanged(item, true)
|
||||||
if (configGlobal.sync.enabled)
|
if (configGlobal.sync.enabled)
|
||||||
util.refresh()
|
util.refresh()
|
||||||
})
|
}).show()
|
||||||
}
|
}
|
||||||
).also {
|
).also {
|
||||||
it.subTextChecked = activity.getSyncInterval(configGlobal.sync.interval)
|
it.subTextChecked = activity.getSyncInterval(configGlobal.sync.interval)
|
||||||
@ -124,7 +124,7 @@ class SettingsSyncCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
subText = R.string.settings_profile_notifications_subtext,
|
subText = R.string.settings_profile_notifications_subtext,
|
||||||
icon = CommunityMaterial.Icon2.cmd_filter_outline
|
icon = CommunityMaterial.Icon2.cmd_filter_outline
|
||||||
) {
|
) {
|
||||||
NotificationFilterDialog(activity)
|
NotificationFilterDialog(activity).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createPropertyActionItem(
|
util.createPropertyActionItem(
|
||||||
|
@ -54,7 +54,7 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
subText = Themes.getThemeNameRes(),
|
subText = Themes.getThemeNameRes(),
|
||||||
icon = CommunityMaterial.Icon3.cmd_palette_outline
|
icon = CommunityMaterial.Icon3.cmd_palette_outline
|
||||||
) {
|
) {
|
||||||
ThemeChooserDialog(activity)
|
ThemeChooserDialog(activity).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
@ -62,7 +62,7 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
subText = R.string.settings_about_language_subtext,
|
subText = R.string.settings_about_language_subtext,
|
||||||
icon = CommunityMaterial.Icon3.cmd_translate
|
icon = CommunityMaterial.Icon3.cmd_translate
|
||||||
) {
|
) {
|
||||||
AppLanguageDialog(activity)
|
AppLanguageDialog(activity).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createPropertyItem(
|
util.createPropertyItem(
|
||||||
@ -81,7 +81,7 @@ class SettingsThemeCard(util: SettingsUtil) : SettingsCard(util) {
|
|||||||
text = R.string.settings_theme_mini_drawer_buttons_text,
|
text = R.string.settings_theme_mini_drawer_buttons_text,
|
||||||
icon = CommunityMaterial.Icon2.cmd_format_list_checks
|
icon = CommunityMaterial.Icon2.cmd_format_list_checks
|
||||||
) {
|
) {
|
||||||
MiniMenuConfigDialog(activity)
|
MiniMenuConfigDialog(activity).show()
|
||||||
},
|
},
|
||||||
|
|
||||||
util.createActionItem(
|
util.createActionItem(
|
||||||
|
@ -4,63 +4,77 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.ui.template
|
package pl.szczodrzynski.edziennik.ui.template
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import android.view.LayoutInflater
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.databinding.DialogTemplateBinding
|
import pl.szczodrzynski.edziennik.databinding.DialogTemplateBinding
|
||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||||
import kotlin.coroutines.CoroutineContext
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a sample dialog using the new style.
|
||||||
|
*
|
||||||
|
* A dialog may subclass the [BaseDialog], [ViewDialog] or [BindingDialog].
|
||||||
|
*
|
||||||
|
* Fields and methods have the preferred order which should be used when writing new code.
|
||||||
|
* The position of the first occurrence of duplicated methods should be used.
|
||||||
|
* Multi-line methods should be followed by a blank line, one-liners may be just joined together.
|
||||||
|
*
|
||||||
|
* Constructor properties should be private.
|
||||||
|
*
|
||||||
|
* [onShow], when not used, should be placed just before the local variables, as a one-liner.
|
||||||
|
* All other multi-line methods go below the local variables part.
|
||||||
|
*/
|
||||||
class TemplateDialog(
|
class TemplateDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val onActionPerformed: (() -> Unit)? = null,
|
private val onActionPerformed: (() -> Unit)? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogTemplateBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "TemplateDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "TemplateDialog"
|
||||||
private lateinit var b: DialogTemplateBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitle(): CharSequence = "Template"
|
||||||
override val coroutineContext: CoroutineContext
|
override fun getTitleRes() = R.string.menu_template
|
||||||
get() = job + Dispatchers.Main
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
|
DialogTemplateBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
// override fun getTitle(): CharSequence = "Template"
|
||||||
|
// override fun getTitleRes() = R.string.menu_template
|
||||||
|
// override fun getMessage() = ""
|
||||||
|
// override fun getMessageRes() = R.string.edziennik_progress_login_template_api
|
||||||
|
// override fun getMessageFormat() =
|
||||||
|
// R.string.card_update_text_format to listOf(
|
||||||
|
// BuildConfig.VERSION_BASE,
|
||||||
|
// "5.0",
|
||||||
|
// )
|
||||||
|
|
||||||
|
// override fun getTitleRes() = R.string.menu_template
|
||||||
|
override fun isCancelable() = true
|
||||||
|
override fun getPositiveButtonText() = R.string.ok
|
||||||
|
override fun getNeutralButtonText() = R.string.reset
|
||||||
|
override fun getNegativeButtonText() = R.string.cancel
|
||||||
|
|
||||||
|
// getSingleChoiceItem / getMultiChoiceItems
|
||||||
|
// getDefaultSelectedItem / getDefaultSelectedItems
|
||||||
|
|
||||||
|
// to convert a map of StringIDs to CharSequences
|
||||||
|
// .mapKeys { (resId, _) -> activity.getString(resId) }
|
||||||
|
|
||||||
|
override suspend fun onShow() = Unit
|
||||||
|
|
||||||
// local variables go here
|
// local variables go here
|
||||||
|
|
||||||
init { run {
|
// onPositiveClick
|
||||||
if (activity.isFinishing)
|
// onNeutralClick
|
||||||
return@run
|
// onNegativeClick
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogTemplateBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.setNeutralButton(R.string.add, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.onClick {
|
// onSingleSelectionChanged
|
||||||
// do custom action on neutral button click
|
// onMultiSelectionChanged
|
||||||
// (does not dismiss the dialog)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.clickMe.onClick {
|
// getRootView
|
||||||
onActionPerformed?.invoke()
|
// onBeforeShow
|
||||||
dialog.dismiss()
|
// onShow
|
||||||
}
|
// onDismiss
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,14 @@
|
|||||||
package pl.szczodrzynski.edziennik.ui.timetable
|
package pl.szczodrzynski.edziennik.ui.timetable
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
import com.mikepenz.iconics.utils.colorInt
|
import com.mikepenz.iconics.utils.colorInt
|
||||||
import com.mikepenz.iconics.utils.sizeDp
|
import com.mikepenz.iconics.utils.sizeDp
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
@ -27,6 +22,7 @@ import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
|||||||
import pl.szczodrzynski.edziennik.ext.onClick
|
import pl.szczodrzynski.edziennik.ext.onClick
|
||||||
import pl.szczodrzynski.edziennik.ext.setText
|
import pl.szczodrzynski.edziennik.ext.setText
|
||||||
import pl.szczodrzynski.edziennik.ui.attendance.AttendanceDetailsDialog
|
import pl.szczodrzynski.edziennik.ui.attendance.AttendanceDetailsDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
||||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||||
@ -34,26 +30,23 @@ import pl.szczodrzynski.edziennik.utils.BetterLink
|
|||||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
|
|
||||||
class LessonDetailsDialog(
|
class LessonDetailsDialog(
|
||||||
val activity: AppCompatActivity,
|
activity: AppCompatActivity,
|
||||||
val lesson: LessonFull,
|
private val lesson: LessonFull,
|
||||||
val attendance: AttendanceFull? = null,
|
private val attendance: AttendanceFull? = null,
|
||||||
val onShowListener: ((tag: String) -> Unit)? = null,
|
onShowListener: ((tag: String) -> Unit)? = null,
|
||||||
val onDismissListener: ((tag: String) -> Unit)? = null
|
onDismissListener: ((tag: String) -> Unit)? = null,
|
||||||
) : CoroutineScope {
|
) : BindingDialog<DialogLessonDetailsBinding>(activity, onShowListener, onDismissListener) {
|
||||||
companion object {
|
|
||||||
private const val TAG = "LessonDetailsDialog"
|
|
||||||
}
|
|
||||||
|
|
||||||
private lateinit var app: App
|
override val TAG = "LessonDetailsDialog"
|
||||||
private lateinit var b: DialogLessonDetailsBinding
|
|
||||||
private lateinit var dialog: AlertDialog
|
|
||||||
|
|
||||||
private val job = Job()
|
override fun getTitleRes(): Int? = null
|
||||||
override val coroutineContext: CoroutineContext
|
override fun inflate(layoutInflater: LayoutInflater) =
|
||||||
get() = job + Dispatchers.Main
|
DialogLessonDetailsBinding.inflate(layoutInflater)
|
||||||
|
|
||||||
|
override fun getPositiveButtonText() = R.string.close
|
||||||
|
override fun getNeutralButtonText() = R.string.add
|
||||||
|
|
||||||
private lateinit var adapter: EventListAdapter
|
private lateinit var adapter: EventListAdapter
|
||||||
private val manager
|
private val manager
|
||||||
@ -61,44 +54,26 @@ class LessonDetailsDialog(
|
|||||||
private val attendanceManager
|
private val attendanceManager
|
||||||
get() = app.attendanceManager
|
get() = app.attendanceManager
|
||||||
|
|
||||||
init { run {
|
override suspend fun onNeutralClick(): Boolean {
|
||||||
if (activity.isFinishing)
|
|
||||||
return@run
|
|
||||||
onShowListener?.invoke(TAG)
|
|
||||||
app = activity.applicationContext as App
|
|
||||||
b = DialogLessonDetailsBinding.inflate(activity.layoutInflater)
|
|
||||||
dialog = MaterialAlertDialogBuilder(activity)
|
|
||||||
.setView(b.root)
|
|
||||||
.setPositiveButton(R.string.close) { dialog, _ ->
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
.setNeutralButton(R.string.add, null)
|
|
||||||
.setOnDismissListener {
|
|
||||||
onDismissListener?.invoke(TAG)
|
|
||||||
}
|
|
||||||
.show()
|
|
||||||
|
|
||||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.onClick {
|
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
activity,
|
activity,
|
||||||
lesson.profileId,
|
lesson.profileId,
|
||||||
defaultLesson = lesson,
|
defaultLesson = lesson,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
|
return NO_DISMISS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun onShow() {
|
||||||
if (App.devMode)
|
if (App.devMode)
|
||||||
b.lessonId.visibility = View.VISIBLE
|
b.lessonId.visibility = View.VISIBLE
|
||||||
|
|
||||||
update()
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun update() {
|
|
||||||
b.lesson = lesson
|
b.lesson = lesson
|
||||||
val lessonDate = lesson.displayDate ?: return
|
val lessonDate = lesson.displayDate ?: return
|
||||||
val lessonTime = lesson.displayStartTime ?: return
|
val lessonTime = lesson.displayStartTime ?: return
|
||||||
b.lessonDate.text = Week.getFullDayName(lessonDate.weekDay) + ", " + lessonDate.formattedString
|
b.lessonDate.text =
|
||||||
|
Week.getFullDayName(lessonDate.weekDay) + ", " + lessonDate.formattedString
|
||||||
|
|
||||||
b.annotationVisible = manager.getAnnotation(activity, lesson, b.annotation)
|
b.annotationVisible = manager.getAnnotation(activity, lesson, b.annotation)
|
||||||
|
|
||||||
@ -145,8 +120,7 @@ class LessonDetailsDialog(
|
|||||||
}
|
}
|
||||||
activity.sendBroadcast(intent)
|
activity.sendBroadcast(intent)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
b.shiftedLayout.visibility = View.GONE
|
b.shiftedLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +169,12 @@ class LessonDetailsDialog(
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
b.attendanceDetails.onClick {
|
b.attendanceDetails.onClick {
|
||||||
AttendanceDetailsDialog(activity, attendance, onShowListener, onDismissListener)
|
AttendanceDetailsDialog(
|
||||||
|
activity = activity,
|
||||||
|
attendance = attendance,
|
||||||
|
onShowListener = onShowListener,
|
||||||
|
onDismissListener = onDismissListener,
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +192,7 @@ class LessonDetailsDialog(
|
|||||||
it,
|
it,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
},
|
},
|
||||||
onEventEditClick = {
|
onEventEditClick = {
|
||||||
EventManualDialog(
|
EventManualDialog(
|
||||||
@ -222,11 +201,15 @@ class LessonDetailsDialog(
|
|||||||
editingEvent = it,
|
editingEvent = it,
|
||||||
onShowListener = onShowListener,
|
onShowListener = onShowListener,
|
||||||
onDismissListener = onDismissListener
|
onDismissListener = onDismissListener
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
app.db.eventDao().getAllByDateTime(lesson.profileId, lessonDate, lessonTime).observe(activity, Observer { events ->
|
app.db.eventDao().getAllByDateTime(
|
||||||
|
lesson.profileId,
|
||||||
|
lessonDate,
|
||||||
|
lessonTime
|
||||||
|
).observe(activity) { events ->
|
||||||
adapter.setAllItems(events)
|
adapter.setAllItems(events)
|
||||||
if (b.eventsView.adapter == null) {
|
if (b.eventsView.adapter == null) {
|
||||||
b.eventsView.adapter = adapter
|
b.eventsView.adapter = adapter
|
||||||
@ -246,7 +229,7 @@ class LessonDetailsDialog(
|
|||||||
b.eventsView.visibility = View.GONE
|
b.eventsView.visibility = View.GONE
|
||||||
b.eventsNoData.visibility = View.VISIBLE
|
b.eventsNoData.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
lesson.displayTeacherName?.let { name ->
|
lesson.displayTeacherName?.let { name ->
|
||||||
lesson.displayTeacherId ?: return@let
|
lesson.displayTeacherId ?: return@let
|
||||||
|
@ -225,7 +225,7 @@ class TimetableDayFragment : LazyFragment(), CoroutineScope {
|
|||||||
activity = activity,
|
activity = activity,
|
||||||
lesson = lessonObj as LessonFull,
|
lesson = lessonObj as LessonFull,
|
||||||
attendance = attendanceObj as AttendanceFull?
|
attendance = attendanceObj as AttendanceFull?
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
|
|||||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||||
.withOnClickListener(View.OnClickListener {
|
.withOnClickListener(View.OnClickListener {
|
||||||
activity.bottomSheet.close()
|
activity.bottomSheet.close()
|
||||||
EventManualDialog(activity, App.profileId, defaultDate = pageSelection)
|
EventManualDialog(activity, App.profileId, defaultDate = pageSelection).show()
|
||||||
}),
|
}),
|
||||||
BottomSheetPrimaryItem(true)
|
BottomSheetPrimaryItem(true)
|
||||||
.withTitle(R.string.menu_generate_block_timetable)
|
.withTitle(R.string.menu_generate_block_timetable)
|
||||||
|
@ -65,7 +65,7 @@ class WebPushFragment : Fragment(), CoroutineScope {
|
|||||||
QrScannerDialog(activity, {
|
QrScannerDialog(activity, {
|
||||||
b.tokenEditText.setText(it.crc32().toString(36).uppercase())
|
b.tokenEditText.setText(it.crc32().toString(36).uppercase())
|
||||||
pairBrowser(browserId = it)
|
pairBrowser(browserId = it)
|
||||||
})
|
}).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ class LessonDialogActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
if (shownDialogs.isEmpty())
|
if (shownDialogs.isEmpty())
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
)
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,11 +87,15 @@ class UserActionManager(val app: App) {
|
|||||||
return
|
return
|
||||||
// show captcha dialog
|
// show captcha dialog
|
||||||
// use passed onSuccess listener, else sync profile
|
// use passed onSuccess listener, else sync profile
|
||||||
LibrusCaptchaDialog(activity, onSuccess = onSuccess ?: { code ->
|
LibrusCaptchaDialog(
|
||||||
|
activity = activity,
|
||||||
|
onSuccess = onSuccess ?: { code ->
|
||||||
EdziennikTask.syncProfile(profileId, arguments = JsonObject(
|
EdziennikTask.syncProfile(profileId, arguments = JsonObject(
|
||||||
"recaptchaCode" to code,
|
"recaptchaCode" to code,
|
||||||
"recaptchaTime" to System.currentTimeMillis()
|
"recaptchaTime" to System.currentTimeMillis()
|
||||||
)).enqueue(activity)
|
)).enqueue(activity)
|
||||||
}, onFailure = onFailure)
|
},
|
||||||
|
onFailure = onFailure
|
||||||
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user