@@ -22,24 +22,31 @@ package com.github.quarck.calnotify.ui
2222import android.app.AlertDialog
2323import android.content.Context
2424import android.content.Intent
25+ import android.content.res.ColorStateList
2526import android.os.Bundle
27+ import android.text.format.DateUtils
2628import android.view.View
29+ import android.widget.DatePicker
2730import android.widget.LinearLayout
2831import android.widget.PopupMenu
2932import android.widget.TextView
33+ import android.widget.TimePicker
3034import android.widget.Toast
3135import androidx.appcompat.app.AppCompatActivity
36+ import com.google.android.material.floatingactionbutton.FloatingActionButton
3237import com.github.quarck.calnotify.Consts
3338import com.github.quarck.calnotify.R
3439import com.github.quarck.calnotify.Settings
3540import com.github.quarck.calnotify.app.ApplicationController
3641import com.github.quarck.calnotify.calendar.CalendarIntents
42+ import com.github.quarck.calnotify.calendar.CalendarProvider
43+ import com.github.quarck.calnotify.calendar.CalendarProviderInterface
3744import com.github.quarck.calnotify.calendar.EventAlertRecord
3845import com.github.quarck.calnotify.calendar.EventDisplayStatus
3946import com.github.quarck.calnotify.calendar.EventOrigin
4047import com.github.quarck.calnotify.calendar.EventStatus
4148import com.github.quarck.calnotify.calendar.AttendanceStatus
42- import com.github.quarck.calnotify.calendar.CalendarProvider
49+ import com.github.quarck.calnotify.utils.adjustCalendarColor
4350import com.github.quarck.calnotify.dismissedeventsstorage.DismissedEventsStorage
4451import com.github.quarck.calnotify.dismissedeventsstorage.EventDismissType
4552import com.github.quarck.calnotify.eventsstorage.EventsStorage
@@ -51,7 +58,11 @@ import com.github.quarck.calnotify.textutils.EventFormatterInterface
5158import com.github.quarck.calnotify.utils.CNPlusClockInterface
5259import com.github.quarck.calnotify.utils.CNPlusSystemClock
5360import com.github.quarck.calnotify.utils.background
61+ import com.github.quarck.calnotify.utils.findOrThrow
62+ import com.github.quarck.calnotify.utils.hourCompat
63+ import com.github.quarck.calnotify.utils.minuteCompat
5464import com.github.quarck.calnotify.utils.setupStatusBarSpacer
65+ import java.util.*
5566
5667/* *
5768 * Activity for pre-actions on upcoming events.
@@ -140,6 +151,7 @@ class PreActionActivity : AppCompatActivity() {
140151 private var eventIsMuted: Boolean = false
141152
142153 private lateinit var snoozePresets: LongArray
154+ private val calendarProvider: CalendarProviderInterface = CalendarProvider
143155
144156 override fun onCreate (savedInstanceState : Bundle ? ) {
145157 super .onCreate(savedInstanceState)
@@ -213,33 +225,75 @@ class PreActionActivity : AppCompatActivity() {
213225 showCustomSnoozeDialog()
214226 }
215227
216- // Mute toggle
217- updateMuteButton()
218- findViewById<TextView >(R .id.pre_action_mute_toggle).setOnClickListener {
219- toggleMute()
228+ // Until specific time
229+ findViewById<TextView >(R .id.pre_action_snooze_until).setOnClickListener {
230+ showSnoozeUntilDatePicker()
220231 }
221232
222- // View in calendar
223- findViewById<TextView >(R .id.pre_action_view_calendar).setOnClickListener {
224- viewInCalendar()
225- }
233+ // Edit FAB
234+ setupEditFab()
226235
227236 // 3-dot menu
228237 findViewById<View >(R .id.pre_action_menu).setOnClickListener { v ->
229238 showMenu(v)
230239 }
231240 }
232241
242+ private fun setupEditFab () {
243+ val fab = findOrThrow<FloatingActionButton >(R .id.pre_action_edit_button)
244+ val calendar = calendarProvider.getCalendarById(this , calendarId)
245+ ? : calendarProvider.createCalendarNotFoundCal(this )
246+
247+ if (! calendar.isReadOnly) {
248+ if (! eventIsRepeating && ! settings.alwaysUseExternalEditor) {
249+ fab.setOnClickListener {
250+ val intent = Intent (this , EditEventActivity ::class .java)
251+ intent.putExtra(EditEventActivity .EVENT_ID , eventId)
252+ startActivity(intent)
253+ finish()
254+ }
255+ } else {
256+ fab.setOnClickListener {
257+ viewInCalendar()
258+ finish()
259+ }
260+ }
261+
262+ val states = arrayOf(
263+ intArrayOf(android.R .attr.state_enabled),
264+ intArrayOf(android.R .attr.state_pressed)
265+ )
266+ val colors = intArrayOf(
267+ eventColor.adjustCalendarColor(false ),
268+ eventColor.adjustCalendarColor(true )
269+ )
270+ fab.backgroundTintList = ColorStateList (states, colors)
271+ } else {
272+ fab.visibility = View .GONE
273+ }
274+ }
275+
233276 private fun showMenu (anchor : View ) {
234277 val popup = PopupMenu (this , anchor)
235278 popup.menuInflater.inflate(R .menu.pre_action, popup.menu)
236279
280+ popup.menu.findItem(R .id.action_pre_mute)?.isVisible = ! eventIsMuted
281+ popup.menu.findItem(R .id.action_pre_unmute)?.isVisible = eventIsMuted
282+
237283 popup.setOnMenuItemClickListener { item ->
238284 when (item.itemId) {
239285 R .id.action_pre_dismiss -> {
240286 executePreDismiss()
241287 true
242288 }
289+ R .id.action_pre_mute, R .id.action_pre_unmute -> {
290+ toggleMute()
291+ true
292+ }
293+ R .id.action_open_in_calendar -> {
294+ viewInCalendar()
295+ true
296+ }
243297 else -> false
244298 }
245299 }
@@ -303,6 +357,65 @@ class PreActionActivity : AppCompatActivity() {
303357 .show()
304358 }
305359
360+ private fun showSnoozeUntilDatePicker () {
361+ val dialogDate = layoutInflater.inflate(R .layout.dialog_date_picker, null ) ? : return
362+ val datePicker = dialogDate.findOrThrow<DatePicker >(R .id.datePickerCustomSnooze)
363+
364+ val firstDayOfWeek = settings.firstDayOfWeek
365+ if (firstDayOfWeek != - 1 ) {
366+ datePicker.firstDayOfWeek = firstDayOfWeek
367+ }
368+
369+ AlertDialog .Builder (this )
370+ .setView(dialogDate)
371+ .setPositiveButton(R .string.next) { _, _ ->
372+ datePicker.clearFocus()
373+ val date = Calendar .getInstance()
374+ date.set(datePicker.year, datePicker.month, datePicker.dayOfMonth, 0 , 0 , 0 )
375+ showSnoozeUntilTimePicker(date.timeInMillis)
376+ }
377+ .setNegativeButton(R .string.cancel, null )
378+ .create()
379+ .show()
380+ }
381+
382+ private fun showSnoozeUntilTimePicker (dateMillis : Long ) {
383+ val date = Calendar .getInstance()
384+ date.timeInMillis = dateMillis
385+
386+ val dialogTime = layoutInflater.inflate(R .layout.dialog_time_picker, null ) ? : return
387+ val timePicker = dialogTime.findOrThrow<TimePicker >(R .id.timePickerCustomSnooze)
388+ timePicker.setIs24HourView(android.text.format.DateFormat .is24HourFormat(this ))
389+
390+ val title = dialogTime.findOrThrow<TextView >(R .id.textViewSnoozeUntilDate)
391+ title.text = String .format(
392+ resources.getString(R .string.choose_time),
393+ DateUtils .formatDateTime(this , date.timeInMillis, DateUtils .FORMAT_SHOW_DATE )
394+ )
395+
396+ AlertDialog .Builder (this )
397+ .setView(dialogTime)
398+ .setPositiveButton(R .string.snooze) { _, _ ->
399+ timePicker.clearFocus()
400+ date.set(Calendar .HOUR_OF_DAY , timePicker.hourCompat)
401+ date.set(Calendar .MINUTE , timePicker.minuteCompat)
402+
403+ val snoozeUntil = date.timeInMillis + Consts .ALARM_THRESHOLD
404+ if (snoozeUntil > getClock().currentTimeMillis()) {
405+ executePreSnooze(snoozeUntil)
406+ } else {
407+ AlertDialog .Builder (this )
408+ .setTitle(R .string.selected_time_is_in_the_past)
409+ .setNegativeButton(R .string.cancel, null )
410+ .create()
411+ .show()
412+ }
413+ }
414+ .setNegativeButton(R .string.cancel, null )
415+ .create()
416+ .show()
417+ }
418+
306419 private fun executePreSnooze (snoozeUntil : Long ) {
307420 background {
308421 var monitorSuccess = false
@@ -386,12 +499,6 @@ class PreActionActivity : AppCompatActivity() {
386499 )
387500 }
388501
389- private fun updateMuteButton () {
390- // Null check in case activity is destroyed while background task runs
391- val muteView = findViewById<TextView >(R .id.pre_action_mute_toggle) ? : return
392- muteView.text = getString(if (eventIsMuted) R .string.pre_unmute else R .string.pre_mute)
393- }
394-
395502 private fun toggleMute () {
396503 background {
397504 val newMutedState = getMonitorStorage(this ).use { storage ->
@@ -405,7 +512,6 @@ class PreActionActivity : AppCompatActivity() {
405512
406513 runOnUiThread {
407514 if (newMutedState != null ) {
408- updateMuteButton()
409515 val msgRes = if (eventIsMuted) R .string.event_will_be_muted else R .string.event_unmuted
410516 Toast .makeText(this , msgRes, Toast .LENGTH_SHORT ).show()
411517 } else {
0 commit comments