Merge pull request #1442 from KryptKode/feature/show_age_years
Append age/years for birthdays/anniversaries to event title
This commit is contained in:
commit
69a5914ab2
|
@ -63,7 +63,7 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:1b72d7ccff'
|
implementation 'com.github.SimpleMobileTools:Simple-Commons:16ae1d2c03'
|
||||||
implementation 'joda-time:joda-time:2.10.3'
|
implementation 'joda-time:joda-time:2.10.3'
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
|
|
|
@ -606,13 +606,14 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
val selectionArgs = arrayOf(CommonDataKinds.Event.CONTENT_ITEM_TYPE, type.toString())
|
val selectionArgs = arrayOf(CommonDataKinds.Event.CONTENT_ITEM_TYPE, type.toString())
|
||||||
|
|
||||||
val dateFormats = getDateFormats()
|
val dateFormats = getDateFormats()
|
||||||
|
val yearDateFormats = getDateFormatsWithYear()
|
||||||
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
|
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
|
||||||
val importIDs = HashMap<String, Long>()
|
val importIDs = HashMap<String, Long>()
|
||||||
existingEvents.forEach {
|
existingEvents.forEach {
|
||||||
importIDs[it.importId] = it.startTS
|
importIDs[it.importId] = it.startTS
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventTypeId = if (birthdays) getBirthdaysEventTypeId() else getAnniversariesEventTypeId()
|
val eventTypeId = if (birthdays) eventsHelper.getBirthdaysEventTypeId() else eventsHelper.getAnniversariesEventTypeId()
|
||||||
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
|
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
|
||||||
|
|
||||||
queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor ->
|
queryCursor(uri, projection, selection, selectionArgs, showErrors = true) { cursor ->
|
||||||
|
@ -624,15 +625,17 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
try {
|
try {
|
||||||
val formatter = SimpleDateFormat(format, Locale.getDefault())
|
val formatter = SimpleDateFormat(format, Locale.getDefault())
|
||||||
val date = formatter.parse(startDate)
|
val date = formatter.parse(startDate)
|
||||||
if (date.year < 70) {
|
val flags = if (format in yearDateFormats) {
|
||||||
date.year = 70
|
FLAG_ALL_DAY
|
||||||
|
} else {
|
||||||
|
FLAG_ALL_DAY or FLAG_MISSING_YEAR
|
||||||
}
|
}
|
||||||
|
|
||||||
val timestamp = date.time / 1000L
|
val timestamp = date.time / 1000L
|
||||||
val lastUpdated = cursor.getLongValue(CommonDataKinds.Event.CONTACT_LAST_UPDATED_TIMESTAMP)
|
val lastUpdated = cursor.getLongValue(CommonDataKinds.Event.CONTACT_LAST_UPDATED_TIMESTAMP)
|
||||||
val event = Event(
|
val event = Event(
|
||||||
null, timestamp, timestamp, name, reminder1Minutes = reminders[0], reminder2Minutes = reminders[1],
|
null, timestamp, timestamp, name, reminder1Minutes = reminders[0], reminder2Minutes = reminders[1],
|
||||||
reminder3Minutes = reminders[2], importId = contactId, timeZone = DateTimeZone.getDefault().id, flags = FLAG_ALL_DAY,
|
reminder3Minutes = reminders[2], importId = contactId, timeZone = DateTimeZone.getDefault().id, flags = flags,
|
||||||
repeatInterval = YEAR, repeatRule = REPEAT_SAME_DAY, eventType = eventTypeId, source = source, lastUpdated = lastUpdated
|
repeatInterval = YEAR, repeatRule = REPEAT_SAME_DAY, eventType = eventTypeId, source = source, lastUpdated = lastUpdated
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -681,7 +684,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val eventTypeId = if (birthdays) getBirthdaysEventTypeId() else getAnniversariesEventTypeId()
|
val eventTypeId = if (birthdays) eventsHelper.getBirthdaysEventTypeId() else eventsHelper.getAnniversariesEventTypeId()
|
||||||
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
|
val source = if (birthdays) SOURCE_CONTACT_BIRTHDAY else SOURCE_CONTACT_ANNIVERSARY
|
||||||
|
|
||||||
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
|
val existingEvents = if (birthdays) eventsDB.getBirthdays() else eventsDB.getAnniversaries()
|
||||||
|
@ -743,26 +746,6 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||||
callback(eventsFound, eventsAdded)
|
callback(eventsFound, eventsAdded)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBirthdaysEventTypeId(): Long {
|
|
||||||
val birthdays = getString(R.string.birthdays)
|
|
||||||
var eventTypeId = eventsHelper.getEventTypeIdWithTitle(birthdays)
|
|
||||||
if (eventTypeId == -1L) {
|
|
||||||
val eventType = EventType(null, birthdays, resources.getColor(R.color.default_birthdays_color))
|
|
||||||
eventTypeId = eventsHelper.insertOrUpdateEventTypeSync(eventType)
|
|
||||||
}
|
|
||||||
return eventTypeId
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAnniversariesEventTypeId(): Long {
|
|
||||||
val anniversaries = getString(R.string.anniversaries)
|
|
||||||
var eventTypeId = eventsHelper.getEventTypeIdWithTitle(anniversaries)
|
|
||||||
if (eventTypeId == -1L) {
|
|
||||||
val eventType = EventType(null, anniversaries, resources.getColor(R.color.default_anniversaries_color))
|
|
||||||
eventTypeId = eventsHelper.insertOrUpdateEventTypeSync(eventType)
|
|
||||||
}
|
|
||||||
return eventTypeId
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateView(view: Int) {
|
private fun updateView(view: Int) {
|
||||||
calendar_fab.beVisibleIf(view != YEARLY_VIEW && view != WEEKLY_VIEW)
|
calendar_fab.beVisibleIf(view != YEARLY_VIEW && view != WEEKLY_VIEW)
|
||||||
config.storedView = view
|
config.storedView = view
|
||||||
|
|
|
@ -93,6 +93,7 @@ const val REPEAT_ORDER_WEEKDAY = 4 // i.e. every 4th sunday
|
||||||
// special event flags
|
// special event flags
|
||||||
const val FLAG_ALL_DAY = 1
|
const val FLAG_ALL_DAY = 1
|
||||||
const val FLAG_IS_PAST_EVENT = 2
|
const val FLAG_IS_PAST_EVENT = 2
|
||||||
|
const val FLAG_MISSING_YEAR = 4
|
||||||
|
|
||||||
// constants related to ICS file exporting / importing
|
// constants related to ICS file exporting / importing
|
||||||
const val BEGIN_CALENDAR = "BEGIN:VCALENDAR"
|
const val BEGIN_CALENDAR = "BEGIN:VCALENDAR"
|
||||||
|
@ -129,6 +130,7 @@ const val SEQUENCE = "SEQUENCE"
|
||||||
// this tag isn't a standard ICS tag, but there's no official way of adding a category color in an ics file
|
// this tag isn't a standard ICS tag, but there's no official way of adding a category color in an ics file
|
||||||
const val CATEGORY_COLOR = "X-SMT-CATEGORY-COLOR:"
|
const val CATEGORY_COLOR = "X-SMT-CATEGORY-COLOR:"
|
||||||
const val CATEGORY_COLOR_LEGACY = "CATEGORY_COLOR:"
|
const val CATEGORY_COLOR_LEGACY = "CATEGORY_COLOR:"
|
||||||
|
const val MISSING_YEAR = "X-SMT-MISSING-YEAR:"
|
||||||
|
|
||||||
const val DISPLAY = "DISPLAY"
|
const val DISPLAY = "DISPLAY"
|
||||||
const val EMAIL = "EMAIL"
|
const val EMAIL = "EMAIL"
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.simplemobiletools.calendar.pro.helpers
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.collection.LongSparseArray
|
import androidx.collection.LongSparseArray
|
||||||
|
import com.simplemobiletools.calendar.pro.R
|
||||||
import com.simplemobiletools.calendar.pro.extensions.*
|
import com.simplemobiletools.calendar.pro.extensions.*
|
||||||
import com.simplemobiletools.calendar.pro.models.Event
|
import com.simplemobiletools.calendar.pro.models.Event
|
||||||
import com.simplemobiletools.calendar.pro.models.EventType
|
import com.simplemobiletools.calendar.pro.models.EventType
|
||||||
|
@ -259,6 +260,9 @@ class EventsHelper(val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getEventsSync(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean, callback: (events: ArrayList<Event>) -> Unit) {
|
fun getEventsSync(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean, callback: (events: ArrayList<Event>) -> Unit) {
|
||||||
|
val birthDayEventId = getBirthdaysEventTypeId(createIfNotExists = false)
|
||||||
|
val anniversaryEventId = getAnniversariesEventTypeId(createIfNotExists = false)
|
||||||
|
|
||||||
var events = if (applyTypeFilter) {
|
var events = if (applyTypeFilter) {
|
||||||
val displayEventTypes = context.config.displayEventTypes
|
val displayEventTypes = context.config.displayEventTypes
|
||||||
if (displayEventTypes.isEmpty()) {
|
if (displayEventTypes.isEmpty()) {
|
||||||
|
@ -294,12 +298,46 @@ class EventsHelper(val context: Context) {
|
||||||
|
|
||||||
events.forEach {
|
events.forEach {
|
||||||
it.updateIsPastEvent()
|
it.updateIsPastEvent()
|
||||||
|
val originalEvent = eventsDB.getEventWithId(it.id!!)
|
||||||
|
if (originalEvent != null &&
|
||||||
|
(birthDayEventId != -1L && it.eventType == birthDayEventId) or
|
||||||
|
(anniversaryEventId != -1L && it.eventType == anniversaryEventId)
|
||||||
|
) {
|
||||||
|
val eventStartDate = Formatter.getDateFromTS(it.startTS)
|
||||||
|
val originalEventStartDate = Formatter.getDateFromTS(originalEvent.startTS)
|
||||||
|
if (it.hasMissingYear().not()) {
|
||||||
|
val years = (eventStartDate.year - originalEventStartDate.year).coerceAtLeast(0)
|
||||||
|
if (years > 0) {
|
||||||
|
it.title = "${it.title} ($years)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
it.color = eventTypeColors.get(it.eventType) ?: config.primaryColor
|
it.color = eventTypeColors.get(it.eventType) ?: config.primaryColor
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(events)
|
callback(events)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getBirthdaysEventTypeId(createIfNotExists: Boolean = true): Long {
|
||||||
|
val birthdays = context.getString(R.string.birthdays)
|
||||||
|
var eventTypeId = getEventTypeIdWithTitle(birthdays)
|
||||||
|
if (eventTypeId == -1L && createIfNotExists) {
|
||||||
|
val eventType = EventType(null, birthdays, context.resources.getColor(R.color.default_birthdays_color))
|
||||||
|
eventTypeId = insertOrUpdateEventTypeSync(eventType)
|
||||||
|
}
|
||||||
|
return eventTypeId
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAnniversariesEventTypeId(createIfNotExists: Boolean = true): Long {
|
||||||
|
val anniversaries = context.getString(R.string.anniversaries)
|
||||||
|
var eventTypeId = getEventTypeIdWithTitle(anniversaries)
|
||||||
|
if (eventTypeId == -1L && createIfNotExists) {
|
||||||
|
val eventType = EventType(null, anniversaries, context.resources.getColor(R.color.default_anniversaries_color))
|
||||||
|
eventTypeId = insertOrUpdateEventTypeSync(eventType)
|
||||||
|
}
|
||||||
|
return eventTypeId
|
||||||
|
}
|
||||||
|
|
||||||
fun getRepeatableEventsFor(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean = false): List<Event> {
|
fun getRepeatableEventsFor(fromTS: Long, toTS: Long, eventId: Long = -1L, applyTypeFilter: Boolean = false): List<Event> {
|
||||||
val events = if (applyTypeFilter) {
|
val events = if (applyTypeFilter) {
|
||||||
val displayEventTypes = context.config.displayEventTypes
|
val displayEventTypes = context.config.displayEventTypes
|
||||||
|
|
|
@ -23,7 +23,13 @@ class IcsExporter {
|
||||||
private var eventsFailed = 0
|
private var eventsFailed = 0
|
||||||
private var calendars = ArrayList<CalDAVCalendar>()
|
private var calendars = ArrayList<CalDAVCalendar>()
|
||||||
|
|
||||||
fun exportEvents(activity: BaseSimpleActivity, outputStream: OutputStream?, events: ArrayList<Event>, showExportingToast: Boolean, callback: (result: ExportResult) -> Unit) {
|
fun exportEvents(
|
||||||
|
activity: BaseSimpleActivity,
|
||||||
|
outputStream: OutputStream?,
|
||||||
|
events: ArrayList<Event>,
|
||||||
|
showExportingToast: Boolean,
|
||||||
|
callback: (result: ExportResult) -> Unit
|
||||||
|
) {
|
||||||
if (outputStream == null) {
|
if (outputStream == null) {
|
||||||
callback(EXPORT_FAIL)
|
callback(EXPORT_FAIL)
|
||||||
return
|
return
|
||||||
|
@ -58,6 +64,7 @@ class IcsExporter {
|
||||||
event.startTS.let { out.writeLn("$DTSTART:${Formatter.getExportedTime(it * 1000L)}") }
|
event.startTS.let { out.writeLn("$DTSTART:${Formatter.getExportedTime(it * 1000L)}") }
|
||||||
event.endTS.let { out.writeLn("$DTEND:${Formatter.getExportedTime(it * 1000L)}") }
|
event.endTS.let { out.writeLn("$DTEND:${Formatter.getExportedTime(it * 1000L)}") }
|
||||||
}
|
}
|
||||||
|
event.hasMissingYear().let { out.writeLn("$MISSING_YEAR${if (it) 1 else 0}") }
|
||||||
|
|
||||||
out.writeLn("$DTSTAMP$exportTime")
|
out.writeLn("$DTSTAMP$exportTime")
|
||||||
out.writeLn("$STATUS$CONFIRMED")
|
out.writeLn("$STATUS$CONFIRMED")
|
||||||
|
@ -73,11 +80,13 @@ class IcsExporter {
|
||||||
out.writeLn(END_CALENDAR)
|
out.writeLn(END_CALENDAR)
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(when {
|
callback(
|
||||||
eventsExported == 0 -> EXPORT_FAIL
|
when {
|
||||||
eventsFailed > 0 -> EXPORT_PARTIAL
|
eventsExported == 0 -> EXPORT_FAIL
|
||||||
else -> EXPORT_OK
|
eventsFailed > 0 -> EXPORT_PARTIAL
|
||||||
})
|
else -> EXPORT_OK
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,6 +128,10 @@ class IcsImporter(val activity: SimpleActivity) {
|
||||||
if (color.trimStart('-').areDigitsOnly()) {
|
if (color.trimStart('-').areDigitsOnly()) {
|
||||||
curCategoryColor = Integer.parseInt(color)
|
curCategoryColor = Integer.parseInt(color)
|
||||||
}
|
}
|
||||||
|
} else if (line.startsWith(MISSING_YEAR)) {
|
||||||
|
if (line.substring(MISSING_YEAR.length) == "1") {
|
||||||
|
curFlags = curFlags or FLAG_MISSING_YEAR
|
||||||
|
}
|
||||||
} else if (line.startsWith(CATEGORIES) && !overrideFileEventTypes) {
|
} else if (line.startsWith(CATEGORIES) && !overrideFileEventTypes) {
|
||||||
val categories = line.substring(CATEGORIES.length)
|
val categories = line.substring(CATEGORIES.length)
|
||||||
tryAddCategories(categories)
|
tryAddCategories(categories)
|
||||||
|
|
|
@ -138,6 +138,7 @@ data class Event(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getIsAllDay() = flags and FLAG_ALL_DAY != 0
|
fun getIsAllDay() = flags and FLAG_ALL_DAY != 0
|
||||||
|
fun hasMissingYear() = flags and FLAG_MISSING_YEAR != 0
|
||||||
|
|
||||||
fun getReminders() = setOf(
|
fun getReminders() = setOf(
|
||||||
Reminder(reminder1Minutes, reminder1Type),
|
Reminder(reminder1Minutes, reminder1Type),
|
||||||
|
|
Loading…
Reference in New Issue