diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9762e9bbf..3920aeb0e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,6 +6,7 @@ plugins { alias(libs.plugins.android) alias(libs.plugins.kotlinAndroid) alias(libs.plugins.ksp) + alias(libs.plugins.parcelize) base } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt index 917e8d556..bc6f9cfb2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/EventActivity.kt @@ -24,8 +24,6 @@ import android.widget.RelativeLayout import com.google.android.material.timepicker.MaterialTimePicker import com.google.android.material.timepicker.MaterialTimePicker.INPUT_MODE_CLOCK import com.google.android.material.timepicker.TimeFormat -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.adapters.AutoCompleteTextViewAdapter import com.simplemobiletools.calendar.pro.databinding.ActivityEventBinding @@ -171,7 +169,7 @@ class EventActivity : SimpleActivity() { putInt(REPEAT_RULE, mRepeatRule) putLong(REPEAT_LIMIT, mRepeatLimit) - putString(ATTENDEES, getAllAttendees(false)) + putParcelableArrayList(ATTENDEES, getAllAttendees(false)) putInt(AVAILABILITY, mAvailability) putInt(EVENT_COLOR, mEventColor) @@ -213,8 +211,7 @@ class EventActivity : SimpleActivity() { mRepeatRule = getInt(REPEAT_RULE) mRepeatLimit = getLong(REPEAT_LIMIT) - val token = object : TypeToken>() {}.type - mAttendees = Gson().fromJson>(getString(ATTENDEES), token) ?: ArrayList() + mAttendees = getParcelableArrayList(ATTENDEES) ?: arrayListOf() mEventTypeId = getLong(EVENT_TYPE_ID) mEventCalendarId = getInt(EVENT_CALENDAR_ID) @@ -507,8 +504,7 @@ class EventActivity : SimpleActivity() { mAvailability = mEvent.availability mEventColor = mEvent.color - val token = object : TypeToken>() {}.type - mAttendees = Gson().fromJson>(mEvent.attendees, token) ?: ArrayList() + mAttendees = mEvent.attendees.toMutableList() as ArrayList checkRepeatTexts(mRepeatInterval) checkAttendees() @@ -1310,7 +1306,7 @@ class EventActivity : SimpleActivity() { flags = mEvent.flags.addBitIf(binding.eventAllDay.isChecked, FLAG_ALL_DAY) repeatLimit = if (repeatInterval == 0) 0 else mRepeatLimit repeatRule = mRepeatRule - attendees = if (mEventCalendarId == STORED_LOCALLY_ONLY) "" else getAllAttendees(true) + attendees = if (mEventCalendarId == STORED_LOCALLY_ONLY) emptyList() else getAllAttendees(true) eventType = newEventType lastUpdated = System.currentTimeMillis() source = newSource @@ -1641,7 +1637,7 @@ class EventActivity : SimpleActivity() { private fun updateAttendees() { val currentCalendar = calDAVHelper.getCalDAVCalendars("", true).firstOrNull { it.id == mEventCalendarId } mAttendees.forEach { - it.isMe = it.email == currentCalendar?.accountName + it.isMe = it.email == currentCalendar?.ownerName } mAttendees.sortWith(compareBy @@ -1729,7 +1725,7 @@ class EventActivity : SimpleActivity() { autoCompleteView.focusSearch(View.FOCUS_DOWN)?.requestFocus() attendeeHolder.apply { - root.beVisible() + eventContactAttendee.beVisible() val attendeeStatusBackground = resources.getDrawable(R.drawable.attendee_status_circular_background) (attendeeStatusBackground as LayerDrawable).findDrawableByLayerId(R.id.attendee_status_circular_background) @@ -1817,7 +1813,7 @@ class EventActivity : SimpleActivity() { } } - private fun getAllAttendees(isSavingEvent: Boolean): String { + private fun getAllAttendees(isSavingEvent: Boolean): ArrayList { var attendees = ArrayList() mSelectedContacts.forEach { attendees.add(it) @@ -1831,15 +1827,15 @@ class EventActivity : SimpleActivity() { if (mEvent.id == null && isSavingEvent && attendees.isNotEmpty()) { val currentCalendar = calDAVHelper.getCalDAVCalendars("", true).firstOrNull { it.id == mEventCalendarId } - mAvailableContacts.firstOrNull { it.email == currentCalendar?.accountName }?.apply { - attendees = attendees.filter { it.email != currentCalendar?.accountName }.toMutableList() as ArrayList + mAvailableContacts.firstOrNull { it.email == currentCalendar?.ownerName }?.apply { + attendees = attendees.filter { it.email != currentCalendar?.ownerName }.toMutableList() as ArrayList status = Attendees.ATTENDEE_STATUS_ACCEPTED relationship = Attendees.RELATIONSHIP_ORGANIZER attendees.add(this) } } - return Gson().toJson(attendees) + return attendees } private fun getNames(): List { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetListConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetListConfigureActivity.kt index e15266f88..f5bcd57b1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetListConfigureActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetListConfigureActivity.kt @@ -232,36 +232,24 @@ class WidgetListConfigureActivity : SimpleActivity() { var time = dateTime.withHourOfDay(7) listItems.add( - ListEvent( - 1, - time.seconds(), - time.plusMinutes(30).seconds(), - getString(R.string.sample_title_1), - getString(R.string.sample_description_1), - false, - getProperPrimaryColor(), - "", - false, - false, - false, - false + ListEvent.empty.copy( + id = 1, + startTS = time.seconds(), + endTS = time.plusMinutes(30).seconds(), + title = getString(R.string.sample_title_1), + description = getString(R.string.sample_description_1), + color = getProperPrimaryColor(), ) ) time = dateTime.withHourOfDay(8) listItems.add( - ListEvent( - 2, - time.seconds(), - time.plusHours(1).seconds(), - getString(R.string.sample_title_2), - getString(R.string.sample_description_2), - false, - getProperPrimaryColor(), - "", - false, - false, - false, - false + ListEvent.empty.copy( + id = 2, + startTS = time.seconds(), + endTS = time.plusHours(1).seconds(), + title = getString(R.string.sample_title_2), + description = getString(R.string.sample_description_2), + color = getProperPrimaryColor(), ) ) @@ -272,53 +260,35 @@ class WidgetListConfigureActivity : SimpleActivity() { time = dateTime.withHourOfDay(8) listItems.add( - ListEvent( - 3, - time.seconds(), - time.plusHours(1).seconds(), - getString(R.string.sample_title_3), - "", - false, - getProperPrimaryColor(), - "", - false, - false, - false, - false + ListEvent.empty.copy( + id = 3, + startTS = time.seconds(), + endTS = time.plusHours(1).seconds(), + title = getString(R.string.sample_title_3), + description = "", + color = getProperPrimaryColor(), ) ) time = dateTime.withHourOfDay(13) listItems.add( - ListEvent( - 4, - time.seconds(), - time.plusHours(1).seconds(), - getString(R.string.sample_title_4), - getString(R.string.sample_description_4), - false, - getProperPrimaryColor(), - "", - false, - false, - false, - false + ListEvent.empty.copy( + id = 4, + startTS = time.seconds(), + endTS = time.plusHours(1).seconds(), + title = getString(R.string.sample_title_4), + description = getString(R.string.sample_description_4), + color = getProperPrimaryColor(), ) ) time = dateTime.withHourOfDay(18) listItems.add( - ListEvent( - 5, - time.seconds(), - time.plusMinutes(10).seconds(), - getString(R.string.sample_title_5), - "", - false, - getProperPrimaryColor(), - "", - false, - false, - false, - false + ListEvent.empty.copy( + id = 5, + startTS = time.seconds(), + endTS = time.plusMinutes(10).seconds(), + title = getString(R.string.sample_title_5), + description = "", + color = getProperPrimaryColor(), ) ) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/DayEventsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/DayEventsAdapter.kt index b94af644e..a9ce96abf 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/DayEventsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/DayEventsAdapter.kt @@ -90,7 +90,7 @@ class DayEventsAdapter(activity: SimpleActivity, val events: ArrayList, r eventItemHolder.isSelected = selectedKeys.contains(event.id?.toInt()) eventItemHolder.background.applyColorFilter(textColor) eventItemTitle.text = event.title - eventItemTitle.checkViewStrikeThrough(event.isTaskCompleted()) + eventItemTitle.checkViewStrikeThrough(event.shouldStrikeThrough()) eventItemTime.text = if (event.getIsAllDay()) allDayString else Formatter.getTimeFromTS(activity, event.startTS) if (event.startTS != event.endTS) { val startDayCode = Formatter.getDayCodeFromTS(event.startTS) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListAdapter.kt index 33b541a5c..e29ef3301 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListAdapter.kt @@ -136,7 +136,7 @@ class EventListAdapter( eventItemHolder.isSelected = selectedKeys.contains(listEvent.hashCode()) eventItemHolder.background.applyColorFilter(textColor) eventItemTitle.text = listEvent.title - eventItemTitle.checkViewStrikeThrough(listEvent.isTaskCompleted) + eventItemTitle.checkViewStrikeThrough(listEvent.shouldStrikeThrough()) eventItemTime.text = if (listEvent.isAllDay) allDayString else Formatter.getTimeFromTS(activity, listEvent.startTS) if (listEvent.startTS != listEvent.endTS) { if (!listEvent.isAllDay) { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListWidgetAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListWidgetAdapter.kt index d643f3788..daa4a6bc1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListWidgetAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/EventListWidgetAdapter.kt @@ -6,10 +6,7 @@ import android.graphics.Paint import android.widget.RemoteViews import android.widget.RemoteViewsService import com.simplemobiletools.calendar.pro.R -import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.extensions.eventsHelper -import com.simplemobiletools.calendar.pro.extensions.getWidgetFontSize -import com.simplemobiletools.calendar.pro.extensions.seconds +import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.helpers.* import com.simplemobiletools.calendar.pro.models.* import com.simplemobiletools.commons.extensions.* @@ -120,7 +117,7 @@ class EventListWidgetAdapter(val context: Context, val intent: Intent) : RemoteV setViewPadding(R.id.event_item_title, normalMargin, 0, smallMargin, 0) } - if (item.isTaskCompleted) { + if (item.shouldStrikeThrough()) { setInt(R.id.event_item_title, "setPaintFlags", Paint.ANTI_ALIAS_FLAG or Paint.STRIKE_THRU_TEXT_FLAG) } else { setInt(R.id.event_item_title, "setPaintFlags", Paint.ANTI_ALIAS_FLAG) @@ -226,18 +223,19 @@ class EventListWidgetAdapter(val context: Context, val intent: Intent) : RemoteV } val listEvent = ListEvent( - event.id!!, - event.startTS, - event.endTS, - event.title, - event.description, - event.getIsAllDay(), - event.color, - event.location, - event.isPastEvent, - event.repeatInterval > 0, - event.isTask(), - event.isTaskCompleted() + id = event.id!!, + startTS = event.startTS, + endTS = event.endTS, + title = event.title, + description = event.description, + isAllDay = event.getIsAllDay(), + color = event.color, + location = event.location, + isPastEvent = event.isPastEvent, + isRepeatable = event.repeatInterval > 0, + isTask = event.isTask(), + isTaskCompleted = event.isTaskCompleted(), + isAttendeeInviteDeclined = event.isAttendeeInviteDeclined() ) listItems.add(listEvent) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt index ad40259a6..1b69ca2ca 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Context.kt @@ -601,7 +601,7 @@ fun Context.addDayEvents(day: DayMonthly, linearLayout: LinearLayout, res: Resou dayMonthlyEventId.apply { setTextColor(textColor) text = it.title.replace(" ", "\u00A0") // allow word break by char - checkViewStrikeThrough(it.isTaskCompleted()) + checkViewStrikeThrough(it.shouldStrikeThrough()) contentDescription = it.title } @@ -669,7 +669,8 @@ fun Context.getEventListItems(events: List, addSectionDays: Boolean = tru it.isPastEvent, it.repeatInterval > 0, it.isTask(), - it.isTaskCompleted() + it.isTaskCompleted(), + it.isAttendeeInviteDeclined() ) listItems.add(listEvent) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Event.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Event.kt index de9908b4c..c31d4f872 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Event.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Event.kt @@ -40,3 +40,5 @@ fun Event.maybeAdjustRepeatLimitCount(original: Event, occurrenceTS: Long) { this.repeatLimit = newRepeatLimit } } + +fun Event.shouldStrikeThrough() = isTaskCompleted() || isAttendeeInviteDeclined() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/ListEvent.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/ListEvent.kt new file mode 100644 index 000000000..406929d18 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/ListEvent.kt @@ -0,0 +1,5 @@ +package com.simplemobiletools.calendar.pro.extensions + +import com.simplemobiletools.calendar.pro.models.ListEvent + +fun ListEvent.shouldStrikeThrough() = isTaskCompleted || isAttendeeInviteDeclined diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/MonthViewEvent.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/MonthViewEvent.kt new file mode 100644 index 000000000..440cd66aa --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/MonthViewEvent.kt @@ -0,0 +1,5 @@ +package com.simplemobiletools.calendar.pro.extensions + +import com.simplemobiletools.calendar.pro.models.MonthViewEvent + +fun MonthViewEvent.shouldStrikeThrough() = isTaskCompleted || isAttendeeInviteDeclined diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt index 9901b212f..691a19798 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt @@ -645,7 +645,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { } text = event.title - checkViewStrikeThrough(event.isTaskCompleted()) + checkViewStrikeThrough(event.shouldStrikeThrough()) contentDescription = text minHeight = if (event.startTS == event.endTS) { @@ -785,7 +785,7 @@ class WeekFragment : Fragment(), WeeklyCalendar { setTextColor(textColor) maxLines = if (event.isTask()) 1 else 2 text = event.title - checkViewStrikeThrough(event.isTaskCompleted()) + checkViewStrikeThrough(event.shouldStrikeThrough()) contentDescription = text } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt index a7df25fd7..b5e3a2e87 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/CalDAVHelper.kt @@ -7,8 +7,6 @@ import android.content.Context import android.graphics.Color import android.provider.CalendarContract.* import android.widget.Toast -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.models.* @@ -46,7 +44,7 @@ class CalDAVHelper(val context: Context) { } } - fetchCalDAVCalendarEvents(calendar.id, localEventType.id!!, showToasts) + fetchCalDAVCalendarEvents(calendar, localEventType.id!!, showToasts) } if (scheduleNextSync) { @@ -151,7 +149,9 @@ class CalDAVHelper(val context: Context) { } @SuppressLint("MissingPermission") - private fun fetchCalDAVCalendarEvents(calendarId: Int, eventTypeId: Long, showToasts: Boolean) { + private fun fetchCalDAVCalendarEvents(calendar: CalDAVCalendar, eventTypeId: Long, showToasts: Boolean) { + val calendarId = calendar.id + val importIdsMap = HashMap() val fetchedEventIds = ArrayList() @@ -213,7 +213,7 @@ class CalDAVHelper(val context: Context) { val originalId = cursor.getStringValue(Events.ORIGINAL_ID) val originalInstanceTime = cursor.getLongValue(Events.ORIGINAL_INSTANCE_TIME) val reminders = getCalDAVEventReminders(id) - val attendees = Gson().toJson(getCalDAVEventAttendees(id)) + val attendees = getCalDAVEventAttendees(id, calendar) val availability = cursor.getIntValue(Events.AVAILABILITY) val status = cursor.getIntValue(Events.STATUS) val color = cursor.getIntValueOrNull(Events.EVENT_COLOR) @@ -394,8 +394,7 @@ class CalDAVHelper(val context: Context) { private fun setupCalDAVEventAttendees(event: Event) { clearEventAttendees(event) - val attendees = Gson().fromJson>(event.attendees, object : TypeToken>() {}.type) ?: ArrayList() - attendees.forEach { + event.attendees.forEach { val contentValues = ContentValues().apply { put(Attendees.ATTENDEE_NAME, it.name) put(Attendees.ATTENDEE_EMAIL, it.email) @@ -573,7 +572,7 @@ class CalDAVHelper(val context: Context) { return reminders.sortedBy { it.minutes } } - private fun getCalDAVEventAttendees(eventId: Long): List { + private fun getCalDAVEventAttendees(eventId: Long, calendar: CalDAVCalendar): List { val attendees = ArrayList() val uri = Attendees.CONTENT_URI val projection = arrayOf( @@ -588,7 +587,7 @@ class CalDAVHelper(val context: Context) { val email = cursor.getStringValue(Attendees.ATTENDEE_EMAIL) ?: "" val status = cursor.getIntValue(Attendees.ATTENDEE_STATUS) val relationship = cursor.getIntValue(Attendees.ATTENDEE_RELATIONSHIP) - val attendee = Attendee(0, name, email, status, "", false, relationship) + val attendee = Attendee(0, name, email, status, "", email == calendar.ownerName, relationship) attendees.add(attendee) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Converters.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Converters.kt index 94472f47f..9be7e0eb7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Converters.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Converters.kt @@ -3,10 +3,12 @@ package com.simplemobiletools.calendar.pro.helpers import androidx.room.TypeConverter import com.google.gson.Gson import com.google.gson.reflect.TypeToken +import com.simplemobiletools.calendar.pro.models.Attendee class Converters { private val gson = Gson() private val stringType = object : TypeToken>() {}.type + private val attendeeType = object : TypeToken>() {}.type @TypeConverter fun jsonToStringList(value: String): List { @@ -25,4 +27,20 @@ class Converters { @TypeConverter fun stringListToJson(list: List) = gson.toJson(list) + + @TypeConverter + fun attendeeListToJson(list: List): String = gson.toJson(list) + + @TypeConverter + fun jsonToAttendeeList(value: String): List { + if (value.isEmpty()) { + return emptyList() + } + + return try { + gson.fromJson>(value, attendeeType) ?: ArrayList() + } catch (e: Exception) { + emptyList() + } + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt index fedc6950c..e119cf0e0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/IcsImporter.kt @@ -249,7 +249,7 @@ class IcsImporter(val activity: SimpleActivity) { curRepeatRule, curRepeatLimit, curRepeatExceptions, - "", + emptyList(), curImportId, DateTimeZone.getDefault().id, curFlags, diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt index b4bca7ec9..fb74792e5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MyWidgetMonthlyProvider.kt @@ -12,10 +12,7 @@ import android.view.View import android.widget.RemoteViews import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.activities.SplashActivity -import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.extensions.getWidgetFontSize -import com.simplemobiletools.calendar.pro.extensions.isWeekendIndex -import com.simplemobiletools.calendar.pro.extensions.launchNewEventOrTaskActivity +import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.calendar.pro.models.Event @@ -155,7 +152,7 @@ class MyWidgetMonthlyProvider : AppWidgetProvider() { applyColorFilter(R.id.day_monthly_task_image, eventTextColor) setInt(R.id.day_monthly_event_background, "setColorFilter", it.color) - if (it.isTaskCompleted()) { + if (it.shouldStrikeThrough()) { setInt(R.id.day_monthly_event_id, "setPaintFlags", Paint.ANTI_ALIAS_FLAG or Paint.STRIKE_THRU_TEXT_FLAG) } else { setInt(R.id.day_monthly_event_id, "setPaintFlags", Paint.ANTI_ALIAS_FLAG) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Attendee.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Attendee.kt index 0309fd313..b74d147c5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Attendee.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Attendee.kt @@ -2,14 +2,25 @@ package com.simplemobiletools.calendar.pro.models import android.content.Context import android.graphics.drawable.Drawable +import android.os.Parcelable import android.provider.CalendarContract import android.widget.ImageView import com.bumptech.glide.Glide import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions +import kotlinx.parcelize.Parcelize -data class Attendee(val contactId: Int, var name: String, val email: String, var status: Int, var photoUri: String, var isMe: Boolean, var relationship: Int) { +@Parcelize +data class Attendee( + val contactId: Int, + var name: String, + val email: String, + var status: Int, + var photoUri: String, + var isMe: Boolean, + var relationship: Int +) : Parcelable { fun getPublicName() = name.ifEmpty { email } fun updateImage(context: Context, imageView: ImageView, placeholder: Drawable) { @@ -17,21 +28,21 @@ data class Attendee(val contactId: Int, var name: String, val email: String, var imageView.setImageDrawable(placeholder) } else { val options = RequestOptions() - .diskCacheStrategy(DiskCacheStrategy.RESOURCE) - .error(placeholder) - .centerCrop() + .diskCacheStrategy(DiskCacheStrategy.RESOURCE) + .error(placeholder) + .centerCrop() Glide.with(context) - .load(photoUri) - .transition(DrawableTransitionOptions.withCrossFade()) - .placeholder(placeholder) - .apply(options) - .apply(RequestOptions.circleCropTransform()) - .into(imageView) + .load(photoUri) + .transition(DrawableTransitionOptions.withCrossFade()) + .placeholder(placeholder) + .apply(options) + .apply(RequestOptions.circleCropTransform()) + .into(imageView) } } fun showStatusImage() = status == CalendarContract.Attendees.ATTENDEE_STATUS_ACCEPTED || - status == CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED || - status == CalendarContract.Attendees.ATTENDEE_STATUS_TENTATIVE + status == CalendarContract.Attendees.ATTENDEE_STATUS_DECLINED || + status == CalendarContract.Attendees.ATTENDEE_STATUS_TENTATIVE } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Event.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Event.kt index c9d225697..315ed828b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Event.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/Event.kt @@ -1,5 +1,6 @@ package com.simplemobiletools.calendar.pro.models +import android.provider.CalendarContract.Attendees import androidx.collection.LongSparseArray import androidx.room.ColumnInfo import androidx.room.Entity @@ -30,7 +31,7 @@ data class Event( @ColumnInfo(name = "repeat_rule") var repeatRule: Int = 0, @ColumnInfo(name = "repeat_limit") var repeatLimit: Long = 0L, @ColumnInfo(name = "repetition_exceptions") var repetitionExceptions: List = emptyList(), - @ColumnInfo(name = "attendees") var attendees: String = "", + @ColumnInfo(name = "attendees") var attendees: List = emptyList(), @ColumnInfo(name = "import_id") var importId: String = "", @ColumnInfo(name = "time_zone") var timeZone: String = "", @ColumnInfo(name = "flags") var flags: Int = 0, @@ -209,4 +210,8 @@ data class Event( DateTimeZone.getDefault().id } } + + fun isAttendeeInviteDeclined() = attendees.any { + it.isMe && it.status == Attendees.ATTENDEE_STATUS_DECLINED + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/ListEvent.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/ListEvent.kt index 512178635..def5ce0ce 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/ListEvent.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/ListEvent.kt @@ -1,6 +1,36 @@ package com.simplemobiletools.calendar.pro.models data class ListEvent( - var id: Long, var startTS: Long, var endTS: Long, var title: String, var description: String, var isAllDay: Boolean, var color: Int, - var location: String, var isPastEvent: Boolean, var isRepeatable: Boolean, var isTask: Boolean, var isTaskCompleted: Boolean -) : ListItem() + var id: Long, + var startTS: Long, + var endTS: Long, + var title: String, + var description: String, + var isAllDay: Boolean, + var color: Int, + var location: String, + var isPastEvent: Boolean, + var isRepeatable: Boolean, + var isTask: Boolean, + var isTaskCompleted: Boolean, + var isAttendeeInviteDeclined: Boolean +) : ListItem() { + + companion object { + val empty = ListEvent( + id = 0, + startTS = 0, + endTS = 0, + title = "", + description = "", + isAllDay = false, + color = 0, + location = "", + isPastEvent = false, + isRepeatable = false, + isTask = false, + isTaskCompleted = false, + isAttendeeInviteDeclined = false + ) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/MonthViewEvent.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/MonthViewEvent.kt index 5fa8b9ded..1caa8a4cc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/MonthViewEvent.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/models/MonthViewEvent.kt @@ -12,5 +12,6 @@ data class MonthViewEvent( val isAllDay: Boolean, val isPastEvent: Boolean, val isTask: Boolean, - val isTaskCompleted: Boolean + val isTaskCompleted: Boolean, + val isAttendeeInviteDeclined: Boolean, ) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt index 6ae6180f4..3c9432024 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt @@ -130,8 +130,19 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con val daysCnt = getEventLastingDaysCount(event) val monthViewEvent = MonthViewEvent( - event.id!!, event.title, event.startTS, event.endTS, event.color, dayIndexOnMonthView, - daysCnt, dayIndexOnMonthView, event.getIsAllDay(), event.isPastEvent, event.isTask(), event.isTaskCompleted() + id = event.id!!, + title = event.title, + startTS = event.startTS, + endTS = event.endTS, + color = event.color, + startDayIndex = dayIndexOnMonthView, + daysCnt = daysCnt, + originalStartDayIndex = dayIndexOnMonthView, + isAllDay = event.getIsAllDay(), + isPastEvent = event.isPastEvent, + isTask = event.isTask(), + isTaskCompleted = event.isTaskCompleted(), + isAttendeeInviteDeclined = event.isAttendeeInviteDeclined() ) allEvents.add(monthViewEvent) } @@ -370,7 +381,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con val curPaint = Paint(eventTitlePaint) curPaint.color = paintColor - curPaint.isStrikeThruText = event.isTaskCompleted + curPaint.isStrikeThruText = event.shouldStrikeThrough() return curPaint } diff --git a/build.gradle.kts b/build.gradle.kts index 287277090..757129902 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android).apply(false) alias(libs.plugins.kotlinAndroid).apply(false) alias(libs.plugins.ksp).apply(false) + alias(libs.plugins.parcelize).apply(false) } tasks.register("clean") { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0687192fc..855acea1d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -45,3 +45,5 @@ room = [ android = { id = "com.android.application", version.ref = "gradlePlugins-agp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } +