Merge pull request #1760 from Naveen3Singh/task_reminders
Add Task reminders
This commit is contained in:
commit
92e8a9a9e4
|
@ -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"
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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!!)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" />
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue