Merge pull request #1760 from Naveen3Singh/task_reminders

Add Task reminders
This commit is contained in:
Tibor Kaputa 2022-06-29 09:14:14 +02:00 committed by GitHub
commit 92e8a9a9e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 347 additions and 40 deletions

View File

@ -191,6 +191,7 @@
<activity
android:name=".activities.SnoozeReminderActivity"
android:excludeFromRecents="true"
android:exported="false"
android:theme="@style/Theme.Transparent" />
@ -252,6 +253,7 @@
android:permission="android.permission.BIND_REMOTEVIEWS" />
<service android:name=".services.SnoozeService" />
<service android:name=".services.MarkCompletedService" />
<service
android:name=".jobs.CalDAVUpdateListener"

View File

@ -1169,7 +1169,7 @@ class EventActivity : SimpleActivity() {
private fun storeEvent(wasRepeatable: Boolean) {
if (mEvent.id == null || mEvent.id == null) {
eventsHelper.insertEvent(mEvent, true, true) {
eventsHelper.insertEvent(mEvent, addToCalDAV = true, showToasts = true) {
hideKeyboard()
if (DateTime.now().isAfter(mEventStartDateTime.millis)) {
@ -1187,7 +1187,7 @@ class EventActivity : SimpleActivity() {
}
} else {
hideKeyboard()
eventsHelper.updateEvent(mEvent, true, true) {
eventsHelper.updateEvent(mEvent, updateAtCalDAV = true, showToasts = true) {
finish()
}
}
@ -1221,7 +1221,7 @@ class EventActivity : SimpleActivity() {
id = null
}
eventsHelper.insertEvent(mEvent, true, true) {
eventsHelper.insertEvent(mEvent, addToCalDAV = true, showToasts = true) {
finish()
}
}
@ -1230,7 +1230,7 @@ class EventActivity : SimpleActivity() {
2 -> {
ensureBackgroundThread {
eventsHelper.addEventRepeatLimit(mEvent.id!!, mEventOccurrenceTS)
eventsHelper.updateEvent(mEvent, true, true) {
eventsHelper.updateEvent(mEvent, updateAtCalDAV = true, showToasts = true) {
finish()
}
}

View File

@ -16,7 +16,7 @@ class SnoozeReminderActivity : AppCompatActivity() {
showPickSecondsDialogHelper(config.snoozeTime, true, cancelCallback = { dialogCancelled() }) {
ensureBackgroundThread {
val eventId = intent.getLongExtra(EVENT_ID, 0L)
val event = eventsDB.getEventWithId(eventId)
val event = eventsDB.getEventOrTaskWithId(eventId)
config.snoozeTime = it / 60
rescheduleReminder(event, it / 60)
runOnUiThread {

View File

@ -8,13 +8,16 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.WindowManager
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.ContextCompat
import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.dialogs.ReminderWarningDialog
import com.simplemobiletools.calendar.pro.dialogs.SelectEventTypeDialog
import com.simplemobiletools.calendar.pro.extensions.*
import com.simplemobiletools.calendar.pro.helpers.*
import com.simplemobiletools.calendar.pro.helpers.Formatter
import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.Reminder
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
@ -26,6 +29,14 @@ class TaskActivity : SimpleActivity() {
private var mEventTypeId = REGULAR_EVENT_TYPE_ID
private lateinit var mTaskDateTime: DateTime
private lateinit var mTask: Event
private var mIsAllDayEvent = false
private var mReminder1Minutes = REMINDER_OFF
private var mReminder2Minutes = REMINDER_OFF
private var mReminder3Minutes = REMINDER_OFF
private var mReminder1Type = REMINDER_NOTIFICATION
private var mReminder2Type = REMINDER_NOTIFICATION
private var mReminder3Type = REMINDER_NOTIFICATION
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -85,6 +96,10 @@ class TaskActivity : SimpleActivity() {
putSerializable(TASK, mTask)
putLong(START_TS, mTaskDateTime.seconds())
putLong(EVENT_TYPE_ID, mEventTypeId)
putInt(REMINDER_1_MINUTES, mReminder1Minutes)
putInt(REMINDER_2_MINUTES, mReminder2Minutes)
putInt(REMINDER_3_MINUTES, mReminder3Minutes)
}
}
@ -100,6 +115,10 @@ class TaskActivity : SimpleActivity() {
mTask = getSerializable(TASK) as Event
mTaskDateTime = Formatter.getDateTimeFromTS(getLong(START_TS))
mEventTypeId = getLong(EVENT_TYPE_ID)
mReminder1Minutes = getInt(REMINDER_1_MINUTES)
mReminder2Minutes = getInt(REMINDER_2_MINUTES)
mReminder3Minutes = getInt(REMINDER_3_MINUTES)
}
updateEventType()
@ -123,12 +142,18 @@ class TaskActivity : SimpleActivity() {
}
} else {
mTask = Event(null)
config.apply {
mReminder1Minutes = if (usePreviousEventReminders && lastEventReminderMinutes1 >= -1) lastEventReminderMinutes1 else defaultReminder1
mReminder2Minutes = if (usePreviousEventReminders && lastEventReminderMinutes2 >= -1) lastEventReminderMinutes2 else defaultReminder2
mReminder3Minutes = if (usePreviousEventReminders && lastEventReminderMinutes3 >= -1) lastEventReminderMinutes3 else defaultReminder3
}
if (savedInstanceState == null) {
setupNewTask()
}
}
task_all_day.setOnCheckedChangeListener { compoundButton, isChecked -> toggleAllDay(isChecked) }
task_all_day.setOnCheckedChangeListener { _, isChecked -> toggleAllDay(isChecked) }
task_all_day_holder.setOnClickListener {
task_all_day.toggle()
}
@ -137,10 +162,27 @@ class TaskActivity : SimpleActivity() {
task_time.setOnClickListener { setupTime() }
event_type_holder.setOnClickListener { showEventTypeDialog() }
event_reminder_1.setOnClickListener {
handleNotificationAvailability {
if (config.wasAlarmWarningShown) {
showReminder1Dialog()
} else {
ReminderWarningDialog(this) {
config.wasAlarmWarningShown = true
showReminder1Dialog()
}
}
}
}
event_reminder_2.setOnClickListener { showReminder2Dialog() }
event_reminder_3.setOnClickListener { showReminder3Dialog() }
if (savedInstanceState == null) {
updateEventType()
updateDateText()
updateTimeText()
updateReminderTexts()
}
}
@ -150,6 +192,13 @@ class TaskActivity : SimpleActivity() {
updateActionBarTitle(getString(R.string.edit_task))
mEventTypeId = mTask.eventType
mReminder1Minutes = mTask.reminder1Minutes
mReminder2Minutes = mTask.reminder2Minutes
mReminder3Minutes = mTask.reminder3Minutes
mReminder1Type = mTask.reminder1Type
mReminder2Type = mTask.reminder2Type
mReminder3Type = mTask.reminder3Type
task_title.setText(mTask.title)
task_description.setText(mTask.description)
task_all_day.isChecked = mTask.getIsAllDay()
@ -177,6 +226,34 @@ class TaskActivity : SimpleActivity() {
return
}
val reminders = getReminders()
if (!task_all_day.isChecked) {
if ((reminders.getOrNull(2)?.minutes ?: 0) < -1) {
reminders.removeAt(2)
}
if ((reminders.getOrNull(1)?.minutes ?: 0) < -1) {
reminders.removeAt(1)
}
if ((reminders.getOrNull(0)?.minutes ?: 0) < -1) {
reminders.removeAt(0)
}
}
val reminder1 = reminders.getOrNull(0) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
val reminder2 = reminders.getOrNull(1) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
val reminder3 = reminders.getOrNull(2) ?: Reminder(REMINDER_OFF, REMINDER_NOTIFICATION)
config.apply {
if (usePreviousEventReminders) {
lastEventReminderMinutes1 = reminder1.minutes
lastEventReminderMinutes2 = reminder2.minutes
lastEventReminderMinutes3 = reminder3.minutes
}
}
config.lastUsedLocalEventTypeId = mEventTypeId
mTask.apply {
startTS = mTaskDateTime.withSecondOfMinute(0).withMillisOfSecond(0).seconds()
@ -187,11 +264,25 @@ class TaskActivity : SimpleActivity() {
lastUpdated = System.currentTimeMillis()
eventType = mEventTypeId
type = TYPE_TASK
reminder1Minutes = mReminder1Minutes
reminder1Type = mReminder1Type
reminder2Minutes = mReminder2Minutes
reminder2Type = mReminder2Type
reminder3Minutes = mReminder3Minutes
reminder3Type = mReminder3Type
}
ensureBackgroundThread {
EventsHelper(this).insertTask(mTask) {
EventsHelper(this).insertTask(mTask, true) {
hideKeyboard()
if (DateTime.now().isAfter(mTaskDateTime.millis)) {
if (mTask.repeatInterval == 0 && mTask.getReminders().any { it.type == REMINDER_NOTIFICATION }) {
notifyEvent(mTask)
}
}
finish()
}
}
@ -223,12 +314,12 @@ class TaskActivity : SimpleActivity() {
private fun setupDate() {
hideKeyboard()
val datepicker = DatePickerDialog(
val datePicker = DatePickerDialog(
this, getDatePickerDialogTheme(), dateSetListener, mTaskDateTime.year, mTaskDateTime.monthOfYear - 1, mTaskDateTime.dayOfMonth
)
datepicker.datePicker.firstDayOfWeek = if (config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY
datepicker.show()
datePicker.datePicker.firstDayOfWeek = if (config.isSundayFirst) Calendar.SUNDAY else Calendar.MONDAY
datePicker.show()
}
private fun setupTime() {
@ -238,11 +329,11 @@ class TaskActivity : SimpleActivity() {
).show()
}
private val dateSetListener = DatePickerDialog.OnDateSetListener { view, year, monthOfYear, dayOfMonth ->
private val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
dateSet(year, monthOfYear, dayOfMonth)
}
private val timeSetListener = TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute ->
private val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hourOfDay, minute ->
timeSet(hourOfDay, minute)
}
@ -300,9 +391,93 @@ class TaskActivity : SimpleActivity() {
}
}
private fun updateReminderTexts() {
updateReminder1Text()
updateReminder2Text()
updateReminder3Text()
}
private fun updateReminder1Text() {
event_reminder_1.text = getFormattedMinutes(mReminder1Minutes)
}
private fun updateReminder2Text() {
event_reminder_2.apply {
beGoneIf(event_reminder_2.isGone() && mReminder1Minutes == REMINDER_OFF)
if (mReminder2Minutes == REMINDER_OFF) {
text = resources.getString(R.string.add_another_reminder)
alpha = 0.4f
} else {
text = getFormattedMinutes(mReminder2Minutes)
alpha = 1f
}
}
}
private fun updateReminder3Text() {
event_reminder_3.apply {
beGoneIf(event_reminder_3.isGone() && (mReminder2Minutes == REMINDER_OFF || mReminder1Minutes == REMINDER_OFF))
if (mReminder3Minutes == REMINDER_OFF) {
text = resources.getString(R.string.add_another_reminder)
alpha = 0.4f
} else {
text = getFormattedMinutes(mReminder3Minutes)
alpha = 1f
}
}
}
private fun handleNotificationAvailability(callback: () -> Unit) {
if (NotificationManagerCompat.from(this).areNotificationsEnabled()) {
callback()
} else {
ConfirmationDialog(this, messageId = R.string.notifications_disabled, positive = R.string.ok, negative = 0) {
callback()
}
}
}
private fun showReminder1Dialog() {
showPickSecondsDialogHelper(mReminder1Minutes, showDuringDayOption = mIsAllDayEvent) {
mReminder1Minutes = if (it == -1 || it == 0) it else it / 60
updateReminderTexts()
}
}
private fun showReminder2Dialog() {
showPickSecondsDialogHelper(mReminder2Minutes, showDuringDayOption = mIsAllDayEvent) {
mReminder2Minutes = if (it == -1 || it == 0) it else it / 60
updateReminderTexts()
}
}
private fun showReminder3Dialog() {
showPickSecondsDialogHelper(mReminder3Minutes, showDuringDayOption = mIsAllDayEvent) {
mReminder3Minutes = if (it == -1 || it == 0) it else it / 60
updateReminderTexts()
}
}
private fun getReminders(): ArrayList<Reminder> {
var reminders = arrayListOf(
Reminder(mReminder1Minutes, mReminder1Type),
Reminder(mReminder2Minutes, mReminder2Type),
Reminder(mReminder3Minutes, mReminder3Type)
)
reminders = reminders.filter { it.minutes != REMINDER_OFF }.sortedBy { it.minutes }.toMutableList() as ArrayList<Reminder>
return reminders
}
private fun showEventTypeDialog() {
hideKeyboard()
SelectEventTypeDialog(this, mEventTypeId, false, true, false, true) {
SelectEventTypeDialog(
activity = this,
currEventType = mEventTypeId,
showCalDAVCalendars = false,
showNewEventTypeOption = true,
addLastUsedOneAsFirstOption = false,
showOnlyWritable = true
) {
mEventTypeId = it.id!!
updateEventType()
}
@ -322,7 +497,11 @@ class TaskActivity : SimpleActivity() {
private fun updateColors() {
updateTextColors(task_scrollview)
task_time_image.applyColorFilter(getProperTextColor())
event_type_image.applyColorFilter(getProperTextColor())
val textColor = getProperTextColor()
arrayOf(
task_time_image, event_reminder_image, event_type_image
).forEach {
it.applyColorFilter(textColor)
}
}
}

View File

@ -37,6 +37,7 @@ import com.simplemobiletools.calendar.pro.interfaces.WidgetsDao
import com.simplemobiletools.calendar.pro.models.*
import com.simplemobiletools.calendar.pro.receivers.CalDAVSyncReceiver
import com.simplemobiletools.calendar.pro.receivers.NotificationReceiver
import com.simplemobiletools.calendar.pro.services.MarkCompletedService
import com.simplemobiletools.calendar.pro.services.SnoozeService
import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.*
@ -95,7 +96,7 @@ fun Context.updateDateWidget() {
}
fun Context.scheduleAllEvents() {
val events = eventsDB.getEventsAtReboot(getNowSeconds())
val events = eventsDB.getEventsOrTasksAtReboot(getNowSeconds())
events.forEach {
scheduleNextEventReminder(it, false)
}
@ -116,9 +117,9 @@ fun Context.scheduleNextEventReminder(event: Event, showToasts: Boolean) {
val now = getNowSeconds()
val reminderSeconds = validReminders.reversed().map { it.minutes * 60 }
eventsHelper.getEvents(now, now + YEAR, event.id!!, false) {
if (it.isNotEmpty()) {
for (curEvent in it) {
eventsHelper.getEvents(now, now + YEAR, event.id!!, false) { events ->
if (events.isNotEmpty()) {
for (curEvent in events) {
for (curReminder in reminderSeconds) {
if (curEvent.getEventStartTS() - curReminder > now) {
scheduleEventIn((curEvent.getEventStartTS() - curReminder) * 1000L, curEvent, showToasts)
@ -196,9 +197,11 @@ fun Context.getRepetitionText(seconds: Int) = when (seconds) {
}
fun Context.notifyRunningEvents() {
eventsHelper.getRunningEvents().filter { it.getReminders().any { it.type == REMINDER_NOTIFICATION } }.forEach {
notifyEvent(it)
}
eventsHelper.getRunningEventsOrTasks()
.filter { it.getReminders().any { reminder -> reminder.type == REMINDER_NOTIFICATION } }
.forEach {
notifyEvent(it)
}
}
fun Context.notifyEvent(originalEvent: Event) {
@ -310,7 +313,12 @@ fun Context.getNotification(pendingIntent: PendingIntent, event: Event, content:
.setAutoCancel(true)
.setSound(Uri.parse(soundUri), config.reminderAudioStream)
.setChannelId(channelId)
.addAction(R.drawable.ic_snooze_vector, getString(R.string.snooze), getSnoozePendingIntent(this, event))
.apply {
if (event.isTask() && !event.isTaskCompleted()) {
addAction(R.drawable.ic_task_vector, getString(R.string.mark_completed), getMarkCompletedPendingIntent(this@getNotification, event))
}
addAction(R.drawable.ic_snooze_vector, getString(R.string.snooze), getSnoozePendingIntent(this@getNotification, event))
}
if (config.vibrateOnReminder) {
val vibrateArray = LongArray(2) { 500 }
@ -334,7 +342,8 @@ fun Context.getNotification(pendingIntent: PendingIntent, event: Event, content:
private fun getFormattedEventTime(startTime: String, endTime: String) = if (startTime == endTime) startTime else "$startTime \u2013 $endTime"
private fun getPendingIntent(context: Context, event: Event): PendingIntent {
val intent = Intent(context, EventActivity::class.java)
val activityClass = getActivityToOpen(event.isTask())
val intent = Intent(context, activityClass)
intent.putExtra(EVENT_ID, event.id)
intent.putExtra(EVENT_OCCURRENCE_TS, event.startTS)
return PendingIntent.getActivity(context, event.id!!.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
@ -351,6 +360,12 @@ private fun getSnoozePendingIntent(context: Context, event: Event): PendingInten
}
}
private fun getMarkCompletedPendingIntent(context: Context, task: Event): PendingIntent {
val intent = Intent(context, MarkCompletedService::class.java).setAction(ACTION_MARK_COMPLETED)
intent.putExtra(EVENT_ID, task.id)
return PendingIntent.getService(context, task.id!!.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
fun Context.rescheduleReminder(event: Event?, minutes: Int) {
if (event != null) {
cancelPendingIntent(event.id!!)

View File

@ -220,6 +220,9 @@ const val AVAILABILITY = "AVAILABILITY"
const val EVENT_TYPE_ID = "EVENT_TYPE_ID"
const val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID"
// actions
const val ACTION_MARK_COMPLETED = "ACTION_MARK_COMPLETED"
fun getNowSeconds() = System.currentTimeMillis() / 1000L
fun isWeekend(i: Int, isSundayFirst: Boolean): Boolean {

View File

@ -123,9 +123,10 @@ class EventsHelper(val context: Context) {
callback?.invoke(event.id!!)
}
fun insertTask(task: Event, callback: () -> Unit) {
eventsDB.insertOrUpdate(task)
fun insertTask(task: Event, showToasts: Boolean, callback: () -> Unit) {
task.id = eventsDB.insertOrUpdate(task)
context.updateWidgets()
context.scheduleNextEventReminder(task, showToasts)
callback()
}
@ -295,7 +296,7 @@ class EventsHelper(val context: Context) {
events.addAll(
if (eventId == -1L) {
eventsDB.getOneTimeEventsFromTo(toTS, fromTS).toMutableList() as ArrayList<Event>
eventsDB.getOneTimeEventsOrTasksFromTo(toTS, fromTS).toMutableList() as ArrayList<Event>
} else {
eventsDB.getOneTimeEventFromToWithId(eventId, toTS, fromTS).toMutableList() as ArrayList<Event>
}
@ -481,9 +482,9 @@ class EventsHelper(val context: Context) {
return events
}
fun getRunningEvents(): List<Event> {
fun getRunningEventsOrTasks(): List<Event> {
val ts = getNowSeconds()
val events = eventsDB.getOneTimeEventsFromTo(ts, ts).toMutableList() as ArrayList<Event>
val events = eventsDB.getOneTimeEventsOrTasksFromTo(ts, ts).toMutableList() as ArrayList<Event>
events.addAll(getRepeatableEventsFor(ts, ts))
return events
}

View File

@ -21,22 +21,22 @@ interface EventsDao {
@Query("SELECT * FROM events WHERE id = :id AND type = $TYPE_TASK")
fun getTaskWithId(id: Long): Event?
@Query("SELECT * FROM events WHERE id = :id AND type = $TYPE_EVENT OR type = $TYPE_TASK")
@Query("SELECT * FROM events WHERE id = :id AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
fun getEventOrTaskWithId(id: Long): Event?
@Query("SELECT * FROM events WHERE import_id = :importId AND type = $TYPE_EVENT")
fun getEventWithImportId(importId: String): Event?
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND repeat_interval = 0 AND type = $TYPE_EVENT")
fun getOneTimeEventsFromTo(toTS: Long, fromTS: Long): List<Event>
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND repeat_interval = 0 AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
fun getOneTimeEventsOrTasksFromTo(toTS: Long, fromTS: Long): List<Event>
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND start_ts >= :fromTS AND event_type IN (:eventTypeIds) AND type = $TYPE_TASK")
fun getTasksFromTo(fromTS: Long, toTS: Long, eventTypeIds: List<Long>): List<Event>
@Query("SELECT * FROM events WHERE id = :id AND start_ts <= :toTS AND end_ts >= :fromTS AND repeat_interval = 0 AND type = $TYPE_EVENT")
@Query("SELECT * FROM events WHERE id = :id AND start_ts <= :toTS AND end_ts >= :fromTS AND repeat_interval = 0 AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
fun getOneTimeEventFromToWithId(id: Long, toTS: Long, fromTS: Long): List<Event>
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND start_ts != 0 AND repeat_interval = 0 AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
@Query("SELECT * FROM events WHERE start_ts <= :toTS AND end_ts >= :fromTS AND start_ts != 0 AND repeat_interval = 0 AND event_type IN (:eventTypeIds) AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
fun getOneTimeEventsFromToWithTypes(toTS: Long, fromTS: Long, eventTypeIds: List<Long>): List<Event>
@Query("SELECT * FROM events WHERE end_ts > :toTS AND repeat_interval = 0 AND event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
@ -76,8 +76,8 @@ interface EventsDao {
fun getEventsWithIds(ids: List<Long>): List<Event>
//val selection = "$COL_REMINDER_MINUTES != -1 AND ($COL_START_TS > ? OR $COL_REPEAT_INTERVAL != 0) AND $COL_START_TS != 0"
@Query("SELECT * FROM events WHERE reminder_1_minutes != -1 AND (start_ts > :currentTS OR repeat_interval != 0) AND start_ts != 0 AND type = $TYPE_EVENT")
fun getEventsAtReboot(currentTS: Long): List<Event>
@Query("SELECT * FROM events WHERE reminder_1_minutes != -1 AND (start_ts > :currentTS OR repeat_interval != 0) AND start_ts != 0 AND (type = $TYPE_EVENT OR type = $TYPE_TASK)")
fun getEventsOrTasksAtReboot(currentTS: Long): List<Event>
@Query("SELECT id FROM events")
fun getEventIds(): List<Long>

View File

@ -31,7 +31,7 @@ class NotificationReceiver : BroadcastReceiver() {
}
context.updateListWidget()
val event = context.eventsDB.getEventWithId(id)
val event = context.eventsDB.getEventOrTaskWithId(id)
if (event == null || event.getReminders().none { it.type == REMINDER_NOTIFICATION } || event.repetitionExceptions.contains(Formatter.getTodayCode())) {
return
}

View File

@ -0,0 +1,27 @@
package com.simplemobiletools.calendar.pro.services
import android.app.IntentService
import android.content.Intent
import com.simplemobiletools.calendar.pro.extensions.cancelNotification
import com.simplemobiletools.calendar.pro.extensions.cancelPendingIntent
import com.simplemobiletools.calendar.pro.extensions.eventsDB
import com.simplemobiletools.calendar.pro.helpers.ACTION_MARK_COMPLETED
import com.simplemobiletools.calendar.pro.helpers.EVENT_ID
import com.simplemobiletools.calendar.pro.helpers.FLAG_TASK_COMPLETED
class MarkCompletedService : IntentService("MarkCompleted") {
@Deprecated("Deprecated in Java")
override fun onHandleIntent(intent: Intent?) {
if (intent != null && intent.action == ACTION_MARK_COMPLETED) {
val taskId = intent.getLongExtra(EVENT_ID, 0L)
val task = eventsDB.getTaskWithId(taskId)
if (task != null) {
task.flags = task.flags or FLAG_TASK_COMPLETED
eventsDB.updateTaskCompletion(task.id!!, task.flags)
cancelPendingIntent(task.id!!)
cancelNotification(task.id!!)
}
}
}
}

View File

@ -11,7 +11,7 @@ class SnoozeService : IntentService("Snooze") {
override fun onHandleIntent(intent: Intent?) {
if (intent != null) {
val eventId = intent.getLongExtra(EVENT_ID, 0L)
val event = eventsDB.getEventWithId(eventId)
val event = eventsDB.getEventOrTaskWithId(eventId)
rescheduleReminder(event, config.snoozeTime)
}
}

View File

@ -203,7 +203,7 @@
style="@style/SettingsSectionLabelStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/event_reminders" />
android:text="@string/reminders" />
<LinearLayout
android:id="@+id/settings_reminders_holder"

View File

@ -72,6 +72,7 @@
android:layout_marginStart="@dimen/small_margin"
android:layout_toEndOf="@+id/task_time_image"
android:background="?attr/selectableItemBackground"
android:paddingStart="@dimen/zero"
android:paddingTop="@dimen/normal_margin"
android:paddingEnd="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin">
@ -113,10 +114,88 @@
tools:text="00:00" />
<ImageView
android:id="@+id/event_caldav_calendar_divider"
android:id="@+id/event_date_time_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@+id/task_date"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:background="@color/divider_grey"
android:importantForAccessibility="no" />
<ImageView
android:id="@+id/event_reminder_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_below="@+id/event_date_time_divider"
android:layout_alignTop="@+id/event_reminder_1"
android:layout_alignBottom="@+id/event_reminder_1"
android:layout_marginStart="@dimen/normal_margin"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_bell_vector" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_reminder_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_date_time_divider"
android:layout_marginStart="@dimen/small_margin"
android:layout_toEndOf="@+id/event_reminder_image"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingStart="@dimen/zero"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:textSize="@dimen/day_text_size"
tools:text="@string/add_another_reminder" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_reminder_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_reminder_1"
android:layout_alignStart="@+id/event_reminder_1"
android:alpha="0.4"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingStart="@dimen/zero"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size"
android:visibility="gone"
tools:text="@string/add_another_reminder" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_reminder_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_reminder_2"
android:layout_alignStart="@+id/event_reminder_1"
android:alpha="0.4"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:lines="1"
android:paddingStart="@dimen/zero"
android:paddingTop="@dimen/activity_margin"
android:paddingEnd="@dimen/activity_margin"
android:paddingBottom="@dimen/activity_margin"
android:text="@string/add_another_reminder"
android:textSize="@dimen/day_text_size"
android:visibility="gone"
tools:text="@string/add_another_reminder" />
<ImageView
android:id="@+id/event_caldav_calendar_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@+id/event_reminder_3"
android:layout_marginTop="@dimen/medium_margin"
android:layout_marginBottom="@dimen/medium_margin"
android:background="@color/divider_grey"
android:importantForAccessibility="no" />

View File

@ -38,4 +38,5 @@
<dimen name="quick_filter_min_width">88dp</dimen>
<dimen name="quick_filter_active_line_size">6dp</dimen>
<dimen name="quick_filter_inactive_line_size">2dp</dimen>
<dimen name="zero">0dp</dimen>
</resources>