From 2cf204ff7952b0260913e9254635fab63ccf0af3 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Fri, 20 Dec 2019 00:40:00 +0100 Subject: [PATCH] [Dialog/BellSync] Implement bell sync dialog. --- .../ui/dialogs/bell/BellSyncDialog.kt | 79 ++++++++++ .../dialogs/bell/BellSyncTimeChooseDialog.kt | 138 ++++++++++++++++++ .../modules/home/cards/HomeTimetableCard.kt | 11 ++ app/src/main/res/drawable/ic_bell.xml | 54 +++++++ app/src/main/res/drawable/ic_bell_wtf.xml | 78 ++++++++++ .../main/res/layout/card_home_timetable.xml | 10 +- app/src/main/res/layout/dialog_bell_sync.xml | 31 ++++ .../layout/dialog_bell_sync_time_choose.xml | 43 ++++++ app/src/main/res/values-en/strings.xml | 5 +- app/src/main/res/values/strings.xml | 6 +- 10 files changed, 451 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncDialog.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncTimeChooseDialog.kt create mode 100644 app/src/main/res/drawable/ic_bell.xml create mode 100644 app/src/main/res/drawable/ic_bell_wtf.xml create mode 100644 app/src/main/res/layout/dialog_bell_sync.xml create mode 100644 app/src/main/res/layout/dialog_bell_sync_time_choose.xml diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncDialog.kt new file mode 100644 index 00000000..7dd3619d --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncDialog.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-20 + */ + +package pl.szczodrzynski.edziennik.ui.dialogs.bell + +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 pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.databinding.DialogBellSyncBinding +import pl.szczodrzynski.edziennik.utils.models.Time +import kotlin.coroutines.CoroutineContext + +class BellSyncDialog( + val activity: AppCompatActivity, + private val bellTime: Time, + val onShowListener: ((tag: String) -> Unit)? = null, + val onDismissListener: ((tag: String) -> Unit)? = null +) : CoroutineScope { + + companion object { + const val TAG = "BellSyncDialog" + } + + private lateinit var job: Job + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + private lateinit var dialog: AlertDialog + private lateinit var b: DialogBellSyncBinding + + private val app by lazy { activity.application as App } + + init { apply { + 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() } + .show() + initView() + }} + + private fun initView() { + b.bellSyncHowto.text = app.getString(R.string.bell_sync_howto, bellTime.stringHM) + + b.bellSyncButton.setOnClickListener { + val now = Time.getNow() + val bellDiff = Time.diff(now, bellTime) + val multiplier = if (bellTime > now) -1 else 1 + app.config.timetable.bellSyncDiff = bellDiff + app.config.timetable.bellSyncMultiplier = multiplier + + MaterialAlertDialogBuilder(activity) + .setTitle(R.string.bell_sync_title) + .setMessage(app.getString(R.string.bell_sync_results, if (multiplier == -1) '-' else '+', bellDiff.stringHMS)) + .setPositiveButton(R.string.ok) { resultsDialog, _ -> + resultsDialog.dismiss() + dialog.dismiss() + if (activity is MainActivity) activity.reloadTarget() + } + .show() + } + + if (Time.diff(Time.getNow(), bellTime) > Time(0, 10, 0)) { // Easter egg ^^ + b.bellSyncButton.setImageDrawable(app.resources.getDrawable(R.drawable.ic_bell_wtf)) // wtf + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncTimeChooseDialog.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncTimeChooseDialog.kt new file mode 100644 index 00000000..3bc88aa9 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/dialogs/bell/BellSyncTimeChooseDialog.kt @@ -0,0 +1,138 @@ +/* + * Copyright (c) Kacper Ziubryniewicz 2019-12-20 + */ + +package pl.szczodrzynski.edziennik.ui.dialogs.bell + +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.coroutines.* +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding +import pl.szczodrzynski.edziennik.onClick +import pl.szczodrzynski.edziennik.utils.TextInputDropDown +import pl.szczodrzynski.edziennik.utils.models.Date +import pl.szczodrzynski.edziennik.utils.models.Time +import kotlin.coroutines.CoroutineContext + +class BellSyncTimeChooseDialog( + val activity: AppCompatActivity, + val onShowListener: ((tag: String) -> Unit)? = null, + val onDismissListener: ((tag: String) -> Unit)? = null +) : CoroutineScope { + + companion object { + const val TAG = "BellSyncTimeChooseDialog" + } + + private lateinit var job: Job + override val coroutineContext: CoroutineContext + get() = job + Dispatchers.Main + + private lateinit var dialog: AlertDialog + private lateinit var b: DialogBellSyncTimeChooseBinding + + private val app by lazy { activity.application as App } + + private val today = Date.getToday() + private val selectedTime: Time? + get() = b.timeDropdown.selected?.id?.let { Time.fromValue(it.toInt()) } + + init { apply { + 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 { + BellSyncDialog(activity, it) + } + } + .setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } + .setNeutralButton(R.string.reset, null) + .setOnDismissListener { + onDismissListener?.invoke(TAG) + } + .show() + + dialog.getButton(AlertDialog.BUTTON_NEUTRAL).onClick { + showResetDialog() + } + + initView() + }} + + private fun initView() { + b.bellSyncHowto.text = app.getString(R.string.bell_sync_choose_howto) + + app.config.timetable.bellSyncDiff?.let { bellDiff -> + val multiplier = app.config.timetable.bellSyncMultiplier + val bellDiffText = (if (multiplier == -1) '-' else '+') + bellDiff.stringHMS + b.bellSyncHowto.text = app.getString(R.string.concat_2_strings, + app.getString(R.string.bell_sync_choose_howto), + app.getString(R.string.bell_sync_current_dialog, bellDiffText) + ) + } + + loadTimeList() + } + + private fun loadTimeList() { launch { + val timeItems = withContext(Dispatchers.Default) { + val lessons = app.db.timetableDao().getForDateNow(App.profileId, today) + val items = mutableListOf() + + lessons.forEach { + items += TextInputDropDown.Item( + it.startTime?.value?.toLong() ?: return@forEach, + app.getString(R.string.bell_sync_lesson_item, it.displaySubjectName, it.startTime?.stringHM), + tag = it + ) + + items += TextInputDropDown.Item( + it.endTime?.value?.toLong() ?: return@forEach, + app.getString(R.string.bell_sync_break_item, it.endTime?.stringHM), + tag = it + ) + } + + items + } + + b.timeDropdown.clear() + b.timeDropdown.append(timeItems) + timeItems.forEachIndexed { index, item -> + val time = Time.fromValue(item.id.toInt()) + if (time < Time.getNow()) { + b.timeDropdown.select(if (timeItems.size > index + 1) timeItems[index + 1] else item) + } + } + + b.timeDropdown.isEnabled = true + // TODO Fix popup cutting off + }} + + 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() + dialog.dismiss() + if (activity is MainActivity) activity.reloadTarget() + } + .setNegativeButton(R.string.no) { dialog, _ -> dialog.dismiss() } + .show() + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt index e3a2feeb..20f9c848 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/modules/home/cards/HomeTimetableCard.kt @@ -22,6 +22,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson import pl.szczodrzynski.edziennik.data.db.modules.timetable.LessonFull import pl.szczodrzynski.edziennik.databinding.CardHomeTimetableBinding +import pl.szczodrzynski.edziennik.ui.dialogs.bell.BellSyncTimeChooseDialog import pl.szczodrzynski.edziennik.ui.modules.home.HomeCard import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardAdapter import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragmentV2 @@ -79,6 +80,16 @@ class HomeTimetableCard( .colorAttr(activity, R.attr.colorIcon) .sizeDp(20)) + b.bellSync.setImageDrawable(IconicsDrawable(activity, CommunityMaterial.Icon.cmd_alarm_bell) + .colorAttr(activity, R.attr.colorIcon) + .sizeDp(20)) + + b.bellSync.setOnClickListener { + BellSyncTimeChooseDialog( + activity + ) + } + // get current bell-sync params app.config.timetable.bellSyncDiff?.let { bellSyncDiffMillis = (it.hour * 60 * 60 * 1000 + it.minute * 60 * 1000 + it.second * 1000).toLong() diff --git a/app/src/main/res/drawable/ic_bell.xml b/app/src/main/res/drawable/ic_bell.xml new file mode 100644 index 00000000..61d88dce --- /dev/null +++ b/app/src/main/res/drawable/ic_bell.xml @@ -0,0 +1,54 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_bell_wtf.xml b/app/src/main/res/drawable/ic_bell_wtf.xml new file mode 100644 index 00000000..e49822fe --- /dev/null +++ b/app/src/main/res/drawable/ic_bell_wtf.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/card_home_timetable.xml b/app/src/main/res/layout/card_home_timetable.xml index 2b456a35..ef6436b0 100644 --- a/app/src/main/res/layout/card_home_timetable.xml +++ b/app/src/main/res/layout/card_home_timetable.xml @@ -48,9 +48,15 @@ android:visibility="gone" tools:src="@sample/settings" /> + - - \ No newline at end of file + diff --git a/app/src/main/res/layout/dialog_bell_sync.xml b/app/src/main/res/layout/dialog_bell_sync.xml new file mode 100644 index 00000000..e8838cc6 --- /dev/null +++ b/app/src/main/res/layout/dialog_bell_sync.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_bell_sync_time_choose.xml b/app/src/main/res/layout/dialog_bell_sync_time_choose.xml new file mode 100644 index 00000000..0859f5a7 --- /dev/null +++ b/app/src/main/res/layout/dialog_bell_sync_time_choose.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 0b0d8503..fd3d8ae4 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -76,10 +76,13 @@ Incorrect format Calibration is impossible, because there are no lessons now. Try again, i.e. in the end of the lesson or break. Remember that you should run this even before planned bell time. \n\nCurrent calibration: %s - Click OK, when the lesson ends. The counter\'s time will be calibrated to the bell time.\n\nPlanned bell time is %s + Click OK, when the bell rings. The counter\'s time will be calibrated to the bell time.\n\nPlanned bell time is %s Do you want to reset the calibration? The bell is inexact by %s%s Calibrate with the school bell + Time of the bell to synchronize + lesson %s (%s) + break (%s) Cancel Go to grades Grades - last 7 days diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 976e17ad..0e4003c6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -98,10 +98,14 @@ Nieprawidłowy format Synchronizacja jest niemożliwa, ponieważ teraz nie ma żadnych lekcji. Spróbuj jeszcze raz np. pod koniec lekcji albo przerwy. Pamiętaj, że powinieneś to uruchomić jeszcze przed planowanym czasem dzwonka. "\n\nAktualna kalibracja to %s" - Kliknij OK, kiedy lekcja się skończy. Licznik czasu zostanie zsynchronizowany z czasem dzwonka.\n\nCzas według planu to %s + Kliknij OK, kiedy dzwonek zadzwoni. Licznik czasu zostanie zsynchronizowany z czasem dzwonka.\n\nCzas według planu to %s + Wybierz najbliższy dzwonek, abyś mógł go zsynchronizować z aplikacją. Czy na pewno zresetować synchronizację? Dzwonek jest niedokładny o %s%s Synchronizacja z dzwonkiem + Godzina dzwonka do synchronizacji + lekcja %s (%s) + przerwa (%s) Anuluj Przejdź do ocen Oceny - ostatnie 7 dni