Add event transparency

This commit is contained in:
Y. Dongchen 2021-07-15 14:22:21 +10:00
parent 1f4a879f11
commit c99a6da2ae
11 changed files with 133 additions and 13 deletions

View File

@ -63,6 +63,7 @@ class EventActivity : SimpleActivity() {
private val REPEAT_LIMIT = "REPEAT_LIMIT" private val REPEAT_LIMIT = "REPEAT_LIMIT"
private val REPEAT_RULE = "REPEAT_RULE" private val REPEAT_RULE = "REPEAT_RULE"
private val ATTENDEES = "ATTENDEES" private val ATTENDEES = "ATTENDEES"
private val AVAILABILITY = "AVAILABILITY"
private val EVENT_TYPE_ID = "EVENT_TYPE_ID" private val EVENT_TYPE_ID = "EVENT_TYPE_ID"
private val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID" private val EVENT_CALENDAR_ID = "EVENT_CALENDAR_ID"
private val SELECT_TIME_ZONE_INTENT = 1 private val SELECT_TIME_ZONE_INTENT = 1
@ -89,6 +90,7 @@ class EventActivity : SimpleActivity() {
private var mAttendeeAutoCompleteViews = ArrayList<MyAutoCompleteTextView>() private var mAttendeeAutoCompleteViews = ArrayList<MyAutoCompleteTextView>()
private var mAvailableContacts = ArrayList<Attendee>() private var mAvailableContacts = ArrayList<Attendee>()
private var mSelectedContacts = ArrayList<Attendee>() private var mSelectedContacts = ArrayList<Attendee>()
private var mAvailability = Attendees.AVAILABILITY_BUSY
private var mStoredEventTypes = ArrayList<EventType>() private var mStoredEventTypes = ArrayList<EventType>()
private var mOriginalTimeZone = DateTimeZone.getDefault().id private var mOriginalTimeZone = DateTimeZone.getDefault().id
private var mOriginalStartTS = 0L private var mOriginalStartTS = 0L
@ -217,6 +219,14 @@ class EventActivity : SimpleActivity() {
} }
} }
event_availability.setOnClickListener {
showAvailabilityPicker(mAvailability) {
mAvailability = it
updateAvailabilityText()
updateAvailabilityImage()
}
}
event_type_holder.setOnClickListener { showEventTypeDialog() } event_type_holder.setOnClickListener { showEventTypeDialog() }
event_all_day.apply { event_all_day.apply {
isChecked = mEvent.flags and FLAG_ALL_DAY != 0 isChecked = mEvent.flags and FLAG_ALL_DAY != 0
@ -350,6 +360,8 @@ class EventActivity : SimpleActivity() {
putString(ATTENDEES, getAllAttendees(false)) putString(ATTENDEES, getAllAttendees(false))
putInt(AVAILABILITY, mAvailability)
putLong(EVENT_TYPE_ID, mEventTypeId) putLong(EVENT_TYPE_ID, mEventTypeId)
putInt(EVENT_CALENDAR_ID, mEventCalendarId) putInt(EVENT_CALENDAR_ID, mEventCalendarId)
} }
@ -376,6 +388,8 @@ class EventActivity : SimpleActivity() {
mReminder2Type = getInt(REMINDER_2_TYPE) mReminder2Type = getInt(REMINDER_2_TYPE)
mReminder3Type = getInt(REMINDER_3_TYPE) mReminder3Type = getInt(REMINDER_3_TYPE)
mAvailability = getInt(AVAILABILITY)
mRepeatInterval = getInt(REPEAT_INTERVAL) mRepeatInterval = getInt(REPEAT_INTERVAL)
mRepeatRule = getInt(REPEAT_RULE) mRepeatRule = getInt(REPEAT_RULE)
mRepeatLimit = getLong(REPEAT_LIMIT) mRepeatLimit = getLong(REPEAT_LIMIT)
@ -410,7 +424,9 @@ class EventActivity : SimpleActivity() {
updateStartTexts() updateStartTexts()
updateEndTexts() updateEndTexts()
updateTimeZoneText() updateTimeZoneText()
updateAttendeesVisibility() updateCalDAVVisibility()
updateAvailabilityText()
updateAvailabilityImage()
} }
private fun setupEditEvent() { private fun setupEditEvent() {
@ -451,6 +467,7 @@ class EventActivity : SimpleActivity() {
mRepeatRule = mEvent.repeatRule mRepeatRule = mEvent.repeatRule
mEventTypeId = mEvent.eventType mEventTypeId = mEvent.eventType
mEventCalendarId = mEvent.getCalDAVCalendarId() mEventCalendarId = mEvent.getCalDAVCalendarId()
mAvailability = mEvent.availability
val token = object : TypeToken<List<Attendee>>() {}.type val token = object : TypeToken<List<Attendee>>() {}.type
mAttendees = Gson().fromJson<ArrayList<Attendee>>(mEvent.attendees, token) ?: ArrayList() mAttendees = Gson().fromJson<ArrayList<Attendee>>(mEvent.attendees, token) ?: ArrayList()
@ -836,17 +853,30 @@ class EventActivity : SimpleActivity() {
} }
} }
private fun showAvailabilityPicker(currentValue: Int, callback: (Int) -> Unit) {
val items = arrayListOf(
RadioItem(Attendees.AVAILABILITY_BUSY, getString(R.string.status_busy)),
RadioItem(Attendees.AVAILABILITY_FREE, getString(R.string.status_free))
)
RadioGroupDialog(this, items, currentValue) {
callback(it as Int)
}
}
private fun updateReminderTypeImages() { private fun updateReminderTypeImages() {
updateReminderTypeImage(event_reminder_1_type, Reminder(mReminder1Minutes, mReminder1Type)) updateReminderTypeImage(event_reminder_1_type, Reminder(mReminder1Minutes, mReminder1Type))
updateReminderTypeImage(event_reminder_2_type, Reminder(mReminder2Minutes, mReminder2Type)) updateReminderTypeImage(event_reminder_2_type, Reminder(mReminder2Minutes, mReminder2Type))
updateReminderTypeImage(event_reminder_3_type, Reminder(mReminder3Minutes, mReminder3Type)) updateReminderTypeImage(event_reminder_3_type, Reminder(mReminder3Minutes, mReminder3Type))
} }
private fun updateAttendeesVisibility() { private fun updateCalDAVVisibility() {
val isSyncedEvent = mEventCalendarId != STORED_LOCALLY_ONLY val isSyncedEvent = mEventCalendarId != STORED_LOCALLY_ONLY
event_attendees_image.beVisibleIf(isSyncedEvent) event_attendees_image.beVisibleIf(isSyncedEvent)
event_attendees_holder.beVisibleIf(isSyncedEvent) event_attendees_holder.beVisibleIf(isSyncedEvent)
event_attendees_divider.beVisibleIf(isSyncedEvent) event_attendees_divider.beVisibleIf(isSyncedEvent)
event_availability_divider.beVisibleIf(isSyncedEvent)
event_availability_image.beVisibleIf(isSyncedEvent)
event_availability.beVisibleIf(isSyncedEvent)
} }
private fun updateReminderTypeImage(view: ImageView, reminder: Reminder) { private fun updateReminderTypeImage(view: ImageView, reminder: Reminder) {
@ -856,6 +886,16 @@ class EventActivity : SimpleActivity() {
view.setImageDrawable(icon) view.setImageDrawable(icon)
} }
private fun updateAvailabilityImage() {
val drawable = if (mAvailability == Attendees.AVAILABILITY_FREE) R.drawable.ic_event_available else R.drawable.ic_event_occupied
val icon = resources.getColoredDrawableWithColor(drawable, config.textColor)
event_availability_image.setImageDrawable(icon)
}
private fun updateAvailabilityText() {
event_availability.text = if (mAvailability == Attendees.AVAILABILITY_FREE) getString(R.string.status_free) else getString(R.string.status_busy)
}
private fun updateRepetitionText() { private fun updateRepetitionText() {
event_repetition.text = getRepetitionText(mRepeatInterval) event_repetition.text = getRepetitionText(mRepeatInterval)
} }
@ -895,7 +935,9 @@ class EventActivity : SimpleActivity() {
config.lastUsedCaldavCalendarId = it config.lastUsedCaldavCalendarId = it
updateCurrentCalendarInfo(getCalendarWithId(calendars, it)) updateCurrentCalendarInfo(getCalendarWithId(calendars, it))
updateReminderTypeImages() updateReminderTypeImages()
updateAttendeesVisibility() updateCalDAVVisibility()
updateAvailabilityText()
updateAvailabilityImage()
} }
} }
} else { } else {
@ -1122,6 +1164,7 @@ class EventActivity : SimpleActivity() {
lastUpdated = System.currentTimeMillis() lastUpdated = System.currentTimeMillis()
source = newSource source = newSource
location = event_location.value location = event_location.value
availability = mAvailability
} }
// recreate the event if it was moved in a different CalDAV calendar // recreate the event if it was moved in a different CalDAV calendar
@ -1648,7 +1691,7 @@ class EventActivity : SimpleActivity() {
val textColor = config.textColor val textColor = config.textColor
arrayOf( arrayOf(
event_time_image, event_time_zone_image, event_repetition_image, event_reminder_image, event_type_image, event_caldav_calendar_image, event_time_image, event_time_zone_image, event_repetition_image, event_reminder_image, event_type_image, event_caldav_calendar_image,
event_reminder_1_type, event_reminder_2_type, event_reminder_3_type, event_attendees_image event_reminder_1_type, event_reminder_2_type, event_reminder_3_type, event_attendees_image, event_availability_image
).forEach { ).forEach {
it.applyColorFilter(textColor) it.applyColorFilter(textColor)
} }

View File

@ -17,7 +17,7 @@ import com.simplemobiletools.calendar.pro.models.Event
import com.simplemobiletools.calendar.pro.models.EventType import com.simplemobiletools.calendar.pro.models.EventType
import java.util.concurrent.Executors import java.util.concurrent.Executors
@Database(entities = [Event::class, EventType::class], version = 3) @Database(entities = [Event::class, EventType::class], version = 4)
@TypeConverters(Converters::class) @TypeConverters(Converters::class)
abstract class EventsDatabase : RoomDatabase() { abstract class EventsDatabase : RoomDatabase() {
@ -41,6 +41,7 @@ abstract class EventsDatabase : RoomDatabase() {
}) })
.addMigrations(MIGRATION_1_2) .addMigrations(MIGRATION_1_2)
.addMigrations(MIGRATION_2_3) .addMigrations(MIGRATION_2_3)
.addMigrations(MIGRATION_3_4)
.build() .build()
db!!.openHelper.setWriteAheadLoggingEnabled(true) db!!.openHelper.setWriteAheadLoggingEnabled(true)
} }
@ -80,5 +81,13 @@ abstract class EventsDatabase : RoomDatabase() {
} }
} }
} }
private val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(database: SupportSQLiteDatabase) {
database.apply {
execSQL("ALTER TABLE events ADD COLUMN availability INTEGER NOT NULL DEFAULT 0")
}
}
}
} }
} }

View File

@ -170,7 +170,9 @@ class CalDAVHelper(val context: Context) {
Events.EVENT_LOCATION, Events.EVENT_LOCATION,
Events.EVENT_TIMEZONE, Events.EVENT_TIMEZONE,
Events.CALENDAR_TIME_ZONE, Events.CALENDAR_TIME_ZONE,
Events.DELETED) Events.DELETED,
Events.AVAILABILITY
)
val selection = "${Events.CALENDAR_ID} = $calendarId" val selection = "${Events.CALENDAR_ID} = $calendarId"
context.queryCursor(uri, projection, selection, showErrors = showToasts) { cursor -> context.queryCursor(uri, projection, selection, showErrors = showToasts) { cursor ->
@ -191,6 +193,7 @@ class CalDAVHelper(val context: Context) {
val originalInstanceTime = cursor.getLongValue(Events.ORIGINAL_INSTANCE_TIME) val originalInstanceTime = cursor.getLongValue(Events.ORIGINAL_INSTANCE_TIME)
val reminders = getCalDAVEventReminders(id) val reminders = getCalDAVEventReminders(id)
val attendees = Gson().toJson(getCalDAVEventAttendees(id)) val attendees = Gson().toJson(getCalDAVEventAttendees(id))
val availability = cursor.getIntValue(Events.AVAILABILITY)
if (endTS == 0L) { if (endTS == 0L) {
val duration = cursor.getStringValue(Events.DURATION) ?: "" val duration = cursor.getStringValue(Events.DURATION) ?: ""
@ -210,7 +213,7 @@ class CalDAVHelper(val context: Context) {
reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type
?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type ?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type
?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule, ?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule,
repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, source = source) repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, source = source, availability = availability)
if (event.getIsAllDay()) { if (event.getIsAllDay()) {
event.startTS = Formatter.getShiftedImportTimestamp(event.startTS) event.startTS = Formatter.getShiftedImportTimestamp(event.startTS)
@ -382,6 +385,7 @@ class CalDAVHelper(val context: Context) {
put(Events.EVENT_TIMEZONE, event.getTimeZoneString()) put(Events.EVENT_TIMEZONE, event.getTimeZoneString())
put(Events.EVENT_LOCATION, event.location) put(Events.EVENT_LOCATION, event.location)
put(Events.STATUS, Events.STATUS_CONFIRMED) put(Events.STATUS, Events.STATUS_CONFIRMED)
put(Events.AVAILABILITY, event.availability)
val repeatRule = Parser().getRepeatCode(event) val repeatRule = Parser().getRepeatCode(event)
if (repeatRule.isEmpty()) { if (repeatRule.isEmpty()) {

View File

@ -113,6 +113,7 @@ const val SUMMARY = "SUMMARY"
const val DESCRIPTION = "DESCRIPTION:" const val DESCRIPTION = "DESCRIPTION:"
const val UID = "UID:" const val UID = "UID:"
const val ACTION = "ACTION:" const val ACTION = "ACTION:"
const val TRANSP = "TRANSP:"
const val ATTENDEE = "ATTENDEE:" const val ATTENDEE = "ATTENDEE:"
const val MAILTO = "mailto:" const val MAILTO = "mailto:"
const val TRIGGER = "TRIGGER" const val TRIGGER = "TRIGGER"
@ -155,6 +156,9 @@ const val FR = "FR"
const val SA = "SA" const val SA = "SA"
const val SU = "SU" const val SU = "SU"
const val OPAQUE = "OPAQUE"
const val TRANSPARENT = "TRANSPARENT"
const val SOURCE_SIMPLE_CALENDAR = "simple-calendar" const val SOURCE_SIMPLE_CALENDAR = "simple-calendar"
const val SOURCE_IMPORTED_ICS = "imported-ics" const val SOURCE_IMPORTED_ICS = "imported-ics"
const val SOURCE_CONTACT_BIRTHDAY = "contact-birthday" const val SOURCE_CONTACT_BIRTHDAY = "contact-birthday"

View File

@ -1,5 +1,6 @@
package com.simplemobiletools.calendar.pro.helpers package com.simplemobiletools.calendar.pro.helpers
import android.provider.CalendarContract.Events
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.extensions.calDAVHelper import com.simplemobiletools.calendar.pro.extensions.calDAVHelper
import com.simplemobiletools.calendar.pro.extensions.eventTypesDB import com.simplemobiletools.calendar.pro.extensions.eventTypesDB
@ -56,6 +57,7 @@ class IcsExporter {
event.eventType.let { out.writeLn("$CATEGORIES${activity.eventTypesDB.getEventTypeWithId(it)?.title}") } event.eventType.let { out.writeLn("$CATEGORIES${activity.eventTypesDB.getEventTypeWithId(it)?.title}") }
event.lastUpdated.let { out.writeLn("$LAST_MODIFIED:${Formatter.getExportedTime(it)}") } event.lastUpdated.let { out.writeLn("$LAST_MODIFIED:${Formatter.getExportedTime(it)}") }
event.location.let { out.writeLn("$LOCATION:$it") } event.location.let { out.writeLn("$LOCATION:$it") }
event.availability.let { out.writeLn("$TRANSP${if (it == Events.AVAILABILITY_FREE) TRANSPARENT else OPAQUE}") }
if (event.getIsAllDay()) { if (event.getIsAllDay()) {
out.writeLn("$DTSTART;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.startTS)}") out.writeLn("$DTSTART;$VALUE=$DATE:${Formatter.getDayCodeFromTS(event.startTS)}")

View File

@ -1,5 +1,6 @@
package com.simplemobiletools.calendar.pro.helpers package com.simplemobiletools.calendar.pro.helpers
import android.provider.CalendarContract.Events
import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.R
import com.simplemobiletools.calendar.pro.activities.SimpleActivity import com.simplemobiletools.calendar.pro.activities.SimpleActivity
import com.simplemobiletools.calendar.pro.extensions.eventsDB import com.simplemobiletools.calendar.pro.extensions.eventsDB
@ -36,6 +37,7 @@ class IcsImporter(val activity: SimpleActivity) {
private var curEventTypeId = REGULAR_EVENT_TYPE_ID private var curEventTypeId = REGULAR_EVENT_TYPE_ID
private var curLastModified = 0L private var curLastModified = 0L
private var curCategoryColor = -2 private var curCategoryColor = -2
private var curAvailability = Events.AVAILABILITY_BUSY
private var isNotificationDescription = false private var isNotificationDescription = false
private var isProperReminderAction = false private var isProperReminderAction = false
private var isSequence = false private var isSequence = false
@ -160,6 +162,8 @@ class IcsImporter(val activity: SimpleActivity) {
curRecurrenceDayCode = Formatter.getDayCodeFromTS(timestamp) curRecurrenceDayCode = Formatter.getDayCodeFromTS(timestamp)
} else if (line.startsWith(SEQUENCE)) { } else if (line.startsWith(SEQUENCE)) {
isSequence = true isSequence = true
} else if (line.startsWith(TRANSP)) {
line.substring(TRANSP.length).let { curAvailability = if (it == TRANSPARENT) Events.AVAILABILITY_FREE else Events.AVAILABILITY_BUSY }
} else if (line.trim() == BEGIN_ALARM) { } else if (line.trim() == BEGIN_ALARM) {
isNotificationDescription = true isNotificationDescription = true
} else if (line.trim() == END_ALARM) { } else if (line.trim() == END_ALARM) {
@ -222,7 +226,8 @@ class IcsImporter(val activity: SimpleActivity) {
curEventTypeId, curEventTypeId,
0, 0,
curLastModified, curLastModified,
source source,
curAvailability
) )
if (event.getIsAllDay() && curEnd > curStart) { if (event.getIsAllDay() && curEnd > curStart) {

View File

@ -37,7 +37,8 @@ data class Event(
@ColumnInfo(name = "event_type") var eventType: Long = REGULAR_EVENT_TYPE_ID, @ColumnInfo(name = "event_type") var eventType: Long = REGULAR_EVENT_TYPE_ID,
@ColumnInfo(name = "parent_id") var parentId: Long = 0, @ColumnInfo(name = "parent_id") var parentId: Long = 0,
@ColumnInfo(name = "last_updated") var lastUpdated: Long = 0L, @ColumnInfo(name = "last_updated") var lastUpdated: Long = 0L,
@ColumnInfo(name = "source") var source: String = SOURCE_SIMPLE_CALENDAR) @ColumnInfo(name = "source") var source: String = SOURCE_SIMPLE_CALENDAR,
@ColumnInfo(name = "availability") var availability: Int = 0)
: Serializable { : Serializable {
companion object { companion object {

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,9h14v10zM5,7L5,5h14v2L5,7zM10.56,17.46l5.93,-5.93 -1.06,-1.06 -4.87,4.87 -2.11,-2.11 -1.06,1.06z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19L5,19L5,9h14v10zM5,7L5,5h14v2L5,7zM8.23,16.41l1.06,1.06 2.44,-2.44 2.44,2.44 1.06,-1.06 -2.44,-2.44 2.44,-2.44 -1.06,-1.06 -2.44,2.44 -2.44,-2.44 -1.06,1.06 2.44,2.44z"/>
</vector>

View File

@ -430,11 +430,45 @@
android:background="@color/divider_grey" android:background="@color/divider_grey"
android:importantForAccessibility="no" /> android:importantForAccessibility="no" />
<ImageView
android:id="@+id/event_availability_image"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignTop="@+id/event_availability"
android:layout_alignBottom="@+id/event_availability"
android:layout_marginStart="@dimen/normal_margin"
android:padding="@dimen/medium_margin"
android:src="@drawable/ic_event_occupied" />
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/event_availability"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/event_attendees_divider"
android:layout_toEndOf="@+id/event_availability_image"
android:layout_marginStart="@dimen/small_margin"
android:layout_marginTop="@dimen/medium_margin"
android:paddingTop="@dimen/normal_margin"
android:paddingBottom="@dimen/normal_margin"
android:paddingEnd="@dimen/activity_margin"
android:background="?attr/selectableItemBackground"
android:textSize="@dimen/day_text_size"
android:text="@string/status_busy" />
<ImageView
android:id="@+id/event_availability_divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_below="@+id/event_availability"
android:layout_marginTop="@dimen/medium_margin"
android:background="@color/divider_grey"
android:importantForAccessibility="no" />
<ImageView <ImageView
android:id="@+id/event_caldav_calendar_image" android:id="@+id/event_caldav_calendar_image"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_below="@+id/event_attendees_divider" android:layout_below="@+id/event_availability_divider"
android:layout_alignTop="@+id/event_caldav_calendar_holder" android:layout_alignTop="@+id/event_caldav_calendar_holder"
android:layout_alignEnd="@+id/event_time_image" android:layout_alignEnd="@+id/event_time_image"
android:layout_alignBottom="@+id/event_caldav_calendar_holder" android:layout_alignBottom="@+id/event_caldav_calendar_holder"
@ -447,7 +481,7 @@
android:id="@+id/event_caldav_calendar_holder" android:id="@+id/event_caldav_calendar_holder"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/event_attendees_divider" android:layout_below="@+id/event_availability_divider"
android:layout_toEndOf="@+id/event_caldav_calendar_image" android:layout_toEndOf="@+id/event_caldav_calendar_image"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"
android:visibility="gone"> android:visibility="gone">

View File

@ -302,9 +302,9 @@
        <b>Reddit:</b>         <b>Reddit:</b>
        https://www.reddit.com/r/SimpleMobileTools         https://www.reddit.com/r/SimpleMobileTools
    </string>     </string><![CDATA[
    <!--     ]]><!--
        Haven't found some strings? There's more at         Haven't found some strings? There's more at
        https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res         https://github.com/SimpleMobileTools/Simple-Commons/tree/master/commons/src/main/res
    -->     -->