diff --git a/CHANGELOG.md b/CHANGELOG.md index ad56b7624..c627c7e24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ Changelog ========== +Version 6.13.1 *(2021-03-10)* +---------------------------- + + * Allow repeating events every fifth weekday + * Properly highlight weekends on widgets, if selected so + * Fixed some CalDAV syncing and .ics file importing issues + +Version 6.13.0 *(2021-02-23)* +---------------------------- + + * Added a new combination of monthly + daily view + * Fixed too big background activity with CalDAV sync enabled + * Fixed some glitches at importing .ics files + * Fixed a glitch at new events having wrong date set by default in some cases + * Added a setting item for quick notification customizing on Android 8+ + * Added some translation and stability improvements + Version 6.12.0 *(2021-02-13)* ---------------------------- diff --git a/app/build.gradle b/app/build.gradle index 861cb94d7..39dc15323 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,15 +11,14 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 29 - buildToolsVersion "29.0.3" + compileSdkVersion 30 defaultConfig { applicationId "com.simplemobiletools.calendar.pro" minSdkVersion 21 - targetSdkVersion 29 - versionCode 191 - versionName "6.12.0" + targetSdkVersion 30 + versionCode 193 + versionName "6.13.1" multiDexEnabled true setProperty("archivesBaseName", "calendar") vectorDrawables.useSupportLibrary = true @@ -64,8 +63,8 @@ android { } dependencies { - implementation 'com.simplemobiletools:commons:5.33.35' - implementation 'joda-time:joda-time:2.10.1' + implementation 'com.simplemobiletools:commons:5.34.21' + implementation 'joda-time:joda-time:2.10.3' implementation 'androidx.multidex:multidex:2.0.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' diff --git a/app/src/main/assets/india.ics b/app/src/main/assets/india.ics index 2bccbe76b..81f369071 100644 --- a/app/src/main/assets/india.ics +++ b/app/src/main/assets/india.ics @@ -67,8 +67,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Bhogi UID:ind_9 -DTSTART;VALUE=DATE:20160114 -DTEND;VALUE=DATE:20160115 +DTSTART;VALUE=DATE:20220113 +DTEND;VALUE=DATE:20220114 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20180113} @@ -92,8 +92,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Maha Shivaratri UID:ind_12 -DTSTART;VALUE=DATE:20160226 -DTEND;VALUE=DATE:20160227 +DTSTART;VALUE=DATE:20220301 +DTEND;VALUE=DATE:20220302 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20170225} @@ -101,16 +101,16 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Solar Eclipse [Total] UID:ind_13 -DTSTART:20160309T005800Z -DTEND:20160309T010200Z +DTSTART;VALUE=DATE:20211204 +DTEND;VALUE=DATE:20211205 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT BEGIN:VEVENT SUMMARY:Holi UID:ind_14 -DTSTART;VALUE=DATE:20160323 -DTEND;VALUE=DATE:20160324 +DTSTART;VALUE=DATE:20210328 +DTEND;VALUE=DATE:20210329 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT @@ -182,16 +182,16 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Sri Ram navami UID:ind_23 -DTSTART;VALUE=DATE:20160415 -DTEND;VALUE=DATE:20160416 +DTSTART;VALUE=DATE:20160421 +DTEND;VALUE=DATE:20160422 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT BEGIN:VEVENT SUMMARY:Mahavir Jayanti UID:ind_24 -DTSTART;VALUE=DATE:20160419 -DTEND;VALUE=DATE:20160420 +DTSTART;VALUE=DATE:20210425 +DTEND;VALUE=DATE:20210426 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20180420} @@ -215,8 +215,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Buddha Purnima UID:ind_27 -DTSTART;VALUE=DATE:20160521 -DTEND;VALUE=DATE:20160522 +DTSTART;VALUE=DATE:20210526 +DTEND;VALUE=DATE:20210527 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20170522} @@ -224,8 +224,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Raksha Bandhan UID:ind_28 -DTSTART;VALUE=DATE:20160705 -DTEND;VALUE=DATE:20160706 +DTSTART;VALUE=DATE:20210822 +DTEND;VALUE=DATE:20210823 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20170706} @@ -233,8 +233,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Parsi New Year UID:ind_29 -DTSTART;VALUE=DATE:20160817 -DTEND;VALUE=DATE:20160818 +DTSTART;VALUE=DATE:20220819 +DTEND;VALUE=DATE:20220820 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20180818} @@ -242,8 +242,8 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Janmashtami UID:ind_30 -DTSTART;VALUE=DATE:20160825 -DTEND;VALUE=DATE:20160826 +DTSTART;VALUE=DATE:20210831 +DTEND;VALUE=DATE:20210901 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 EXDATE:20170826} @@ -251,24 +251,24 @@ END:VEVENT BEGIN:VEVENT SUMMARY:Solar Eclipse [Annular] UID:ind_31 -DTSTART:20160901T070800Z -DTEND:20160901T071200Z +DTSTART;VALUE=DATE:20210610 +DTEND;VALUE=DATE:20210611 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT BEGIN:VEVENT SUMMARY:Ganesh Chaturthi UID:ind_32 -DTSTART;VALUE=DATE:20160905 -DTEND;VALUE=DATE:20160906 +DTSTART;VALUE=DATE:20210910 +DTEND;VALUE=DATE:20210911 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT BEGIN:VEVENT SUMMARY:Onam UID:ind_33 -DTSTART;VALUE=DATE:20160913 -DTEND;VALUE=DATE:20160914 +DTSTART;VALUE=DATE:20220907 +DTEND;VALUE=DATE:20220908 STATUS:CONFIRMED RRULE:FREQ=YEARLY;INTERVAL=1 END:VEVENT diff --git a/app/src/main/assets/japan.ics b/app/src/main/assets/japan.ics index 0adaf3952..3418a5245 100644 --- a/app/src/main/assets/japan.ics +++ b/app/src/main/assets/japan.ics @@ -70,12 +70,13 @@ SUMMARY:海の日 / Umi no hi / Marine Day RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=3MO DTSTART;VALUE=DATE:20070716 DTEND;VALUE=DATE:20070717 +EXDATE:20200720,20210719 END:VEVENT BEGIN:VEVENT STATUS:CONFIRMED UID:jap_10 SUMMARY:体育の日 / Taiiku no hi / Health-Sports Day -RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=2MO +RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=2MO;UNTIL=20191231 DTSTART;VALUE=DATE:20071008 DTEND;VALUE=DATE:20071009 END:VEVENT @@ -99,7 +100,7 @@ BEGIN:VEVENT STATUS:CONFIRMED UID:jap_13 SUMMARY:天皇誕生日 / Tennō tanjōbi / Emperor Akihito's Birthday -RRULE:FREQ=YEARLY;INTERVAL=1 +RRULE:FREQ=YEARLY;INTERVAL=1;UNTIL=20190430 DTSTART;VALUE=DATE:20071223 DTEND;VALUE=DATE:20071224 END:VEVENT @@ -370,6 +371,7 @@ SUMMARY:山の日 / Yama no hi / Mountain Day RRULE:FREQ=YEARLY;INTERVAL=1 DTSTART;VALUE=DATE:20160811 DTEND;VALUE=DATE:20160812 +EXDATE:20200811,20210811 END:VEVENT BEGIN:VEVENT STATUS:CONFIRMED @@ -378,4 +380,105 @@ SUMMARY:振替休日 / Furikae kyūjitsu / Substitute Holiday DTSTART;VALUE=DATE:20190812 DTEND;VALUE=DATE:20190813 END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_52 +SUMMARY:振替休日 / Furikae kyūjitsu / Substitute Holiday +DTSTART;VALUE=DATE:20200224 +DTEND;VALUE=DATE:20200225 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_53 +SUMMARY:振替休日 / Furikae kyūjitsu / Substitute Holiday +DTSTART;VALUE=DATE:20210809 +DTEND;VALUE=DATE:20210810 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_54 +SUMMARY:国民の休日 / Kokumin no kyūjitsu / National Holiday +DTSTART;VALUE=DATE:20190430 +DTEND;VALUE=DATE:20190501 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_55 +SUMMARY:国民の休日 / Kokumin no kyūjitsu / National Holiday +DTSTART;VALUE=DATE:20190502 +DTEND;VALUE=DATE:20190503 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_56 +SUMMARY:即位礼正殿の儀 / Sokuireiseiden no gi +DTSTART;VALUE=DATE:20191022 +DTEND;VALUE=DATE:20191023 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_57 +SUMMARY:即位の日 / Sokui no hi / Emperor Naruhito's Enthronement Day +DTSTART;VALUE=DATE:20190501 +DTEND;VALUE=DATE:20190502 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_58 +SUMMARY:天皇誕生日 / Tennō tanjōbi / Emperor Naruhito's Birthday +RRULE:FREQ=YEARLY;INTERVAL=1 +DTSTART;VALUE=DATE:20200223 +DTEND;VALUE=DATE:20200224 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_59 +SUMMARY:海の日 / Umi no hi / Marine Day +DTSTART;VALUE=DATE:20200723 +DTEND;VALUE=DATE:20200724 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_60 +SUMMARY:海の日 / Umi no hi / Marine Day +DTSTART;VALUE=DATE:20210722 +DTEND;VALUE=DATE:20210723 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_61 +SUMMARY:山の日 / Yama no hi / Mountain Day +DTSTART;VALUE=DATE:20200810 +DTEND;VALUE=DATE:20200811 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_62 +SUMMARY:山の日 / Yama no hi / Mountain Day +DTSTART;VALUE=DATE:20210808 +DTEND;VALUE=DATE:20210809 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_63 +SUMMARY:スポーツの日 / Supōtu o hi / Sports Day +RRULE:FREQ=MONTHLY;INTERVAL=12;BYDAY=2MO +DTSTART;VALUE=DATE:20201012 +DTEND;VALUE=DATE:20201013 +EXDATE:20201012,20211011 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_64 +SUMMARY:スポーツの日 / Supōtu o hi / Sports Day +DTSTART;VALUE=DATE:20200724 +DTEND;VALUE=DATE:20200725 +END:VEVENT +BEGIN:VEVENT +STATUS:CONFIRMED +UID:jap_65 +SUMMARY:スポーツの日 / Supōtu o hi / Sports Day +DTSTART;VALUE=DATE:20210723 +DTEND;VALUE=DATE:20210724 +END:VEVENT END:VCALENDAR 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 8be539d17..c1b05bb43 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 @@ -256,7 +256,8 @@ class EventActivity : SimpleActivity() { 0 } else { val original = if (mOriginalTimeZone.isEmpty()) DateTimeZone.getDefault().id else mOriginalTimeZone - (DateTimeZone.forID(mEvent.getTimeZoneString()).getOffset(System.currentTimeMillis()) - DateTimeZone.forID(original).getOffset(System.currentTimeMillis())) / 1000L + val millis = System.currentTimeMillis() + (DateTimeZone.forID(mEvent.getTimeZoneString()).getOffset(millis) - DateTimeZone.forID(original).getOffset(millis)) / 1000L } val newStartTS = mEventStartDateTime.withSecondOfMinute(0).withMillisOfSecond(0).seconds() - offset @@ -289,9 +290,9 @@ class EventActivity : SimpleActivity() { } val reminders = getReminders() - if (event_title.value != mEvent.title || - event_location.value != mEvent.location || - event_description.value != mEvent.description || + if (event_title.text.toString() != mEvent.title || + event_location.text.toString() != mEvent.location || + event_description.text.toString() != mEvent.description || event_time_zone.text != mEvent.getTimeZoneString() || reminders != mEvent.getReminders() || mRepeatInterval != mEvent.repeatInterval || @@ -644,17 +645,9 @@ class EventActivity : SimpleActivity() { private fun getAvailableMonthlyRepetitionRules(): ArrayList { val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_monthly))) - // split Every Last Sunday and Every Fourth Sunday of the month, if the month has 4 sundays + items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY))) if (isLastWeekDayOfMonth()) { - val order = (mEventStartDateTime.dayOfMonth - 1) / 7 + 1 - if (order == 4) { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY))) - items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) - } else if (order == 5) { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) - } - } else { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY))) + items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) } if (isLastDayOfTheMonth()) { @@ -666,16 +659,9 @@ class EventActivity : SimpleActivity() { private fun getAvailableYearlyRepetitionRules(): ArrayList { val items = arrayListOf(RadioItem(REPEAT_SAME_DAY, getString(R.string.repeat_on_the_same_day_yearly))) + items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY))) if (isLastWeekDayOfMonth()) { - val order = (mEventStartDateTime.dayOfMonth - 1) / 7 + 1 - if (order == 4) { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY))) - items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) - } else if (order == 5) { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) - } - } else { - items.add(RadioItem(REPEAT_ORDER_WEEKDAY, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY))) + items.add(RadioItem(REPEAT_ORDER_WEEKDAY_USE_LAST, getRepeatXthDayInMonthString(true, REPEAT_ORDER_WEEKDAY_USE_LAST))) } return items @@ -711,7 +697,7 @@ class EventActivity : SimpleActivity() { private fun getOrderString(repeatRule: Int): String { val dayOfMonth = mEventStartDateTime.dayOfMonth var order = (dayOfMonth - 1) / 7 + 1 - if (order == 4 && isLastWeekDayOfMonth() && repeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST) { + if (isLastWeekDayOfMonth() && repeatRule == REPEAT_ORDER_WEEKDAY_USE_LAST) { order = -1 } @@ -721,6 +707,7 @@ class EventActivity : SimpleActivity() { 2 -> if (isMale) R.string.second_m else R.string.second_f 3 -> if (isMale) R.string.third_m else R.string.third_f 4 -> if (isMale) R.string.fourth_m else R.string.fourth_f + 5 -> if (isMale) R.string.fifth_m else R.string.fifth_f else -> if (isMale) R.string.last_m else R.string.last_f }) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt index c4c3c7013..50efdff78 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/MainActivity.kt @@ -172,6 +172,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { shouldGoToTodayBeVisible = currentFragments.last().shouldGoToTodayBeVisible() menu.apply { goToTodayButton = findItem(R.id.go_to_today) + findItem(R.id.print).isVisible = config.storedView != MONTHLY_DAILY_VIEW findItem(R.id.filter).isVisible = mShouldFilterBeVisible findItem(R.id.go_to_today).isVisible = shouldGoToTodayBeVisible && !mIsSearchOpen findItem(R.id.go_to_date).isVisible = config.storedView != EVENTS_LIST_VIEW @@ -933,11 +934,11 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { val licenses = LICENSE_JODA val faqItems = arrayListOf( - FAQItem(R.string.faq_1_title_commons, R.string.faq_1_text_commons), - FAQItem(R.string.faq_4_title_commons, R.string.faq_4_text_commons), - FAQItem(R.string.faq_1_title, R.string.faq_1_text), FAQItem(R.string.faq_2_title, R.string.faq_2_text), FAQItem(R.string.faq_3_title, R.string.faq_3_text), + FAQItem(R.string.faq_1_title, R.string.faq_1_text), + FAQItem(R.string.faq_1_title_commons, R.string.faq_1_text_commons), + FAQItem(R.string.faq_4_title_commons, R.string.faq_4_text_commons), FAQItem(R.string.faq_4_title, R.string.faq_4_text), FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons), FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons), @@ -955,7 +956,7 @@ class MainActivity : SimpleActivity(), RefreshRecyclerViewListener { search_results_list.beVisibleIf(events.isNotEmpty()) search_placeholder.beVisibleIf(events.isEmpty()) val listItems = getEventListItems(events) - val eventsAdapter = EventListAdapter(this, listItems, true, this, search_results_list) { + val eventsAdapter = EventListAdapter(this, listItems, true, this, search_results_list, true) { if (it is ListEvent) { Intent(applicationContext, EventActivity::class.java).apply { putExtra(EVENT_ID, it.id) diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt index 9e7f352af..13b658c72 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/SettingsActivity.kt @@ -43,6 +43,7 @@ class SettingsActivity : SimpleActivity() { private fun setupSettingItems() { setupCustomizeColors() + setupCustomizeNotifications() setupUseEnglish() setupManageEventTypes() setupHourFormat() @@ -139,6 +140,13 @@ class SettingsActivity : SimpleActivity() { } } + private fun setupCustomizeNotifications() { + settings_customize_notifications_holder.beVisibleIf(isOreoPlus()) + settings_customize_notifications_holder.setOnClickListener { + launchCustomizeNotificationsIntent() + } + } + private fun setupUseEnglish() { settings_use_english_holder.beVisibleIf(config.wasUseEnglishToggled || Locale.getDefault().language != "en") settings_use_english.isChecked = config.useEnglish @@ -340,11 +348,11 @@ class SettingsActivity : SimpleActivity() { updateReminderSound(it) } }, onAlarmSoundDeleted = { - if (it.uri == config.reminderSoundUri) { - val defaultAlarm = getDefaultAlarmSound(RingtoneManager.TYPE_NOTIFICATION) - updateReminderSound(defaultAlarm) - } - }) + if (it.uri == config.reminderSoundUri) { + val defaultAlarm = getDefaultAlarmSound(RingtoneManager.TYPE_NOTIFICATION) + updateReminderSound(defaultAlarm) + } + }) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetDateConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetDateConfigureActivity.kt index 8852bb13d..31fba1baa 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetDateConfigureActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetDateConfigureActivity.kt @@ -9,12 +9,12 @@ import android.widget.SeekBar import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.helpers.Formatter -import com.simplemobiletools.calendar.pro.helpers.LOW_ALPHA import com.simplemobiletools.calendar.pro.helpers.MyWidgetDateProvider import com.simplemobiletools.commons.dialogs.ColorPickerDialog import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.setFillWithStroke +import com.simplemobiletools.commons.helpers.LOWER_ALPHA import kotlinx.android.synthetic.main.widget_config_date.* class WidgetDateConfigureActivity : SimpleActivity() { @@ -112,7 +112,7 @@ class WidgetDateConfigureActivity : SimpleActivity() { private fun updateColors() { mTextColor = mTextColorWithoutTransparency - mWeakTextColor = mTextColorWithoutTransparency.adjustAlpha(LOW_ALPHA) + mWeakTextColor = mTextColorWithoutTransparency.adjustAlpha(LOWER_ALPHA) mPrimaryColor = config.primaryColor config_text_color.setFillWithStroke(mTextColor, Color.BLACK) 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 29f2c8f50..72cc256e1 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 @@ -46,7 +46,7 @@ class WidgetListConfigureActivity : SimpleActivity() { finish() } - EventListAdapter(this, getListItems(), false, null, config_events_list) {}.apply { + EventListAdapter(this, getListItems(), false, null, config_events_list, true) {}.apply { updateTextColor(mTextColor) config_events_list.adapter = this } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt index 1b0302585..9171af04c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/activities/WidgetMonthlyConfigureActivity.kt @@ -13,7 +13,6 @@ import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.addDayEvents import com.simplemobiletools.calendar.pro.extensions.addDayNumber import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.helpers.LOW_ALPHA import com.simplemobiletools.calendar.pro.helpers.MonthlyCalendarImpl import com.simplemobiletools.calendar.pro.helpers.MyWidgetMonthlyProvider import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar @@ -23,6 +22,7 @@ import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.beVisible import com.simplemobiletools.commons.extensions.setFillWithStroke +import com.simplemobiletools.commons.helpers.LOWER_ALPHA import kotlinx.android.synthetic.main.first_row.* import kotlinx.android.synthetic.main.top_navigation.* import kotlinx.android.synthetic.main.widget_config_monthly.* @@ -127,7 +127,7 @@ class WidgetMonthlyConfigureActivity : SimpleActivity(), MonthlyCalendar { private fun updateColors() { mTextColor = mTextColorWithoutTransparency - mWeakTextColor = mTextColorWithoutTransparency.adjustAlpha(LOW_ALPHA) + mWeakTextColor = mTextColorWithoutTransparency.adjustAlpha(LOWER_ALPHA) mPrimaryColor = config.primaryColor top_left_arrow.applyColorFilter(mTextColor) 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 36cdfd449..225f3c7c5 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 @@ -13,13 +13,13 @@ import com.simplemobiletools.calendar.pro.extensions.shareEvents import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.helpers.ITEM_EVENT import com.simplemobiletools.calendar.pro.helpers.ITEM_EVENT_SIMPLE -import com.simplemobiletools.calendar.pro.helpers.LOW_ALPHA import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.beInvisible import com.simplemobiletools.commons.extensions.beInvisibleIf +import com.simplemobiletools.commons.helpers.LOWER_ALPHA import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.views.MyRecyclerView import kotlinx.android.synthetic.main.event_item_day_view.view.* @@ -136,7 +136,7 @@ class DayEventsAdapter(activity: SimpleActivity, val events: ArrayList, r var newTextColor = textColor if (dimPastEvents && event.isPastEvent && !isPrintVersion) { - newTextColor = newTextColor.adjustAlpha(LOW_ALPHA) + newTextColor = newTextColor.adjustAlpha(LOWER_ALPHA) } event_item_start.setTextColor(newTextColor) 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 188e15212..e27d10b0b 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 @@ -20,6 +20,7 @@ import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.applyColorFilter import com.simplemobiletools.commons.extensions.beInvisible import com.simplemobiletools.commons.extensions.beInvisibleIf +import com.simplemobiletools.commons.helpers.LOWER_ALPHA import com.simplemobiletools.commons.helpers.ensureBackgroundThread import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener import com.simplemobiletools.commons.views.MyRecyclerView @@ -28,7 +29,7 @@ import kotlinx.android.synthetic.main.event_list_section.view.* import java.util.* class EventListAdapter(activity: SimpleActivity, var listItems: ArrayList, val allowLongClick: Boolean, val listener: RefreshRecyclerViewListener?, - recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) { + recyclerView: MyRecyclerView, val tryDimPastEvents: Boolean, itemClick: (Any) -> Unit) : MyRecyclerViewAdapter(activity, recyclerView, null, itemClick) { private val topDivider = resources.getDrawable(R.drawable.divider_width) private val allDayString = resources.getString(R.string.all_day) @@ -176,9 +177,9 @@ class EventListAdapter(activity: SimpleActivity, var listItems: ArrayList= now && !isPrintVersion) { startTextColor = adjustedPrimaryColor @@ -197,7 +198,7 @@ class EventListAdapter(activity: SimpleActivity, var listItems: ArrayList() private var textColor = context.config.widgetTextColor - private var weakTextColor = textColor.adjustAlpha(LOW_ALPHA) + private var weakTextColor = textColor.adjustAlpha(LOWER_ALPHA) private val replaceDescription = context.config.replaceDescription private val dimPastEvents = context.config.dimPastEvents private var mediumFontSize = context.getWidgetFontSize() @@ -157,7 +158,7 @@ class EventListWidgetAdapter(val context: Context) : RemoteViewsService.RemoteVi override fun onDataSetChanged() { textColor = context.config.widgetTextColor - weakTextColor = textColor.adjustAlpha(LOW_ALPHA) + weakTextColor = textColor.adjustAlpha(LOWER_ALPHA) mediumFontSize = context.getWidgetFontSize() val fromTS = DateTime().seconds() - context.config.displayPastEvents * 60 val toTS = DateTime().plusYears(1).seconds() diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt index 42cfd738e..99f332d2e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/adapters/MyMonthDayPagerAdapter.kt @@ -36,4 +36,6 @@ class MyMonthDayPagerAdapter(fm: FragmentManager, private val mCodes: List Unit) { var textColor = rawTextColor if (!day.isThisMonth) - textColor = textColor.adjustAlpha(LOW_ALPHA) + textColor = textColor.adjustAlpha(LOWER_ALPHA) (View.inflate(applicationContext, R.layout.day_monthly_number_view, null) as TextView).apply { setTextColor(textColor) @@ -456,7 +456,7 @@ fun Context.addDayEvents(day: DayMonthly, linearLayout: LinearLayout, res: Resou } } -fun Context.getEventListItems(events: List): ArrayList { +fun Context.getEventListItems(events: List, addSections: Boolean = true): ArrayList { val listItems = ArrayList(events.size) val replaceDescription = config.replaceDescription @@ -481,7 +481,7 @@ fun Context.getEventListItems(events: List): ArrayList { sorted.forEach { val code = Formatter.getDayCodeFromTS(it.startTS) - if (code != prevCode) { + if (code != prevCode && addSections) { val day = Formatter.getDayTitle(this, code) val isToday = day == today val listSection = ListSection(day, code, isToday, !isToday && it.startTS < now) @@ -521,7 +521,6 @@ fun Context.refreshCalDAVCalendars(ids: String, showToasts: Boolean) { } Bundle().apply { - putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true) putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true) accounts.forEach { ContentResolver.requestSync(it, uri.authority, this) @@ -553,3 +552,11 @@ fun Context.printBitmap(bitmap: Bitmap) { printHelper.orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT printHelper.printBitmap(getString(R.string.app_name), bitmap) } + +fun Context.editEvent(event: ListEvent) { + Intent(this, EventActivity::class.java).apply { + putExtra(EVENT_ID, event.id) + putExtra(EVENT_OCCURRENCE_TS, event.startTS) + startActivity(this) + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/EventListFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/EventListFragment.kt index 0c018af26..bca17c990 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/EventListFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/EventListFragment.kt @@ -1,6 +1,5 @@ package com.simplemobiletools.calendar.pro.fragments -import android.content.Intent import android.graphics.drawable.ColorDrawable import android.os.Bundle import android.os.Handler @@ -10,13 +9,10 @@ import android.view.ViewGroup import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.simplemobiletools.calendar.pro.R -import com.simplemobiletools.calendar.pro.activities.EventActivity import com.simplemobiletools.calendar.pro.activities.MainActivity import com.simplemobiletools.calendar.pro.activities.SimpleActivity import com.simplemobiletools.calendar.pro.adapters.EventListAdapter import com.simplemobiletools.calendar.pro.extensions.* -import com.simplemobiletools.calendar.pro.helpers.EVENT_ID -import com.simplemobiletools.calendar.pro.helpers.EVENT_OCCURRENCE_TS import com.simplemobiletools.calendar.pro.helpers.Formatter import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.ListEvent @@ -119,9 +115,9 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener { val currAdapter = mView.calendar_events_list.adapter if (currAdapter == null || forceRecreation) { - EventListAdapter(activity as SimpleActivity, listItems, true, this, mView.calendar_events_list) { + EventListAdapter(activity as SimpleActivity, listItems, true, this, mView.calendar_events_list, true) { if (it is ListEvent) { - editEvent(it) + context?.editEvent(it) } }.apply { mView.calendar_events_list.adapter = this @@ -169,14 +165,6 @@ class EventListFragment : MyFragmentHolder(), RefreshRecyclerViewListener { mView.calendar_empty_list_placeholder.setTextColor(activity!!.config.textColor) } - private fun editEvent(event: ListEvent) { - Intent(context, EventActivity::class.java).apply { - putExtra(EVENT_ID, event.id) - putExtra(EVENT_OCCURRENCE_TS, event.startTS) - startActivity(this) - } - } - private fun fetchPreviousPeriod() { val lastPosition = (mView.calendar_events_list.layoutManager as MyLinearLayoutManager).findLastVisibleItemPosition() bottomItemAtRefresh = (mView.calendar_events_list.adapter as EventListAdapter).listItems[lastPosition] diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt index 2fd34f026..6e312e36c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragment.kt @@ -6,34 +6,43 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.RelativeLayout +import androidx.constraintlayout.widget.ConstraintLayout import androidx.fragment.app.Fragment import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.activities.MainActivity -import com.simplemobiletools.calendar.pro.extensions.config +import com.simplemobiletools.calendar.pro.activities.SimpleActivity +import com.simplemobiletools.calendar.pro.adapters.EventListAdapter +import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.helpers.Config import com.simplemobiletools.calendar.pro.helpers.DAY_CODE import com.simplemobiletools.calendar.pro.helpers.Formatter +import com.simplemobiletools.calendar.pro.helpers.Formatter.YEAR_PATTERN import com.simplemobiletools.calendar.pro.helpers.MonthlyCalendarImpl import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.interfaces.NavigationListener import com.simplemobiletools.calendar.pro.models.DayMonthly +import com.simplemobiletools.calendar.pro.models.Event +import com.simplemobiletools.calendar.pro.models.ListEvent +import com.simplemobiletools.commons.extensions.beVisibleIf +import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener +import kotlinx.android.synthetic.main.fragment_month_day.* import kotlinx.android.synthetic.main.fragment_month_day.view.* import org.joda.time.DateTime -class MonthDayFragment : Fragment(), MonthlyCalendar { - private var mTextColor = 0 +class MonthDayFragment : Fragment(), MonthlyCalendar, RefreshRecyclerViewListener { private var mSundayFirst = false private var mShowWeekNumbers = false private var mDayCode = "" + private var mSelectedDayCode = "" private var mPackageName = "" private var mLastHash = 0L private var mCalendar: MonthlyCalendarImpl? = null + private var mListEvents = ArrayList() var listener: NavigationListener? = null lateinit var mRes: Resources - lateinit var mHolder: RelativeLayout + lateinit var mHolder: ConstraintLayout lateinit var mConfig: Config override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { @@ -42,12 +51,19 @@ class MonthDayFragment : Fragment(), MonthlyCalendar { mPackageName = activity!!.packageName mHolder = view.month_day_calendar_holder mDayCode = arguments!!.getString(DAY_CODE)!! + + val shownMonthDateTime = Formatter.getDateTimeFromCode(mDayCode) + mHolder.month_day_selected_day_label.apply { + text = getMonthLabel(shownMonthDateTime) + setOnClickListener { + (activity as MainActivity).showGoToDateDialog() + } + } + mConfig = context!!.config storeStateVariables() - setupButtons() mCalendar = MonthlyCalendarImpl(this, context!!) - return view } @@ -91,19 +107,85 @@ class MonthDayFragment : Fragment(), MonthlyCalendar { mLastHash = newHash activity?.runOnUiThread { - updateDays(days) + mHolder.month_day_view_wrapper.updateDays(days, false) { + mSelectedDayCode = it.code + updateVisibleEvents() + } + } + + refreshItems() + } + + private fun updateVisibleEvents() { + if (activity == null) { + return + } + + val filtered = mListEvents.filter { + if (mSelectedDayCode.isEmpty()) { + val shownMonthDateTime = Formatter.getDateTimeFromCode(mDayCode) + val startDateTime = Formatter.getDateTimeFromTS(it.startTS) + shownMonthDateTime.year == startDateTime.year && shownMonthDateTime.monthOfYear == startDateTime.monthOfYear + } else { + Formatter.getDayCodeFromTS(it.startTS) == mSelectedDayCode + } + } + + val listItems = activity!!.getEventListItems(filtered, false) + if (mSelectedDayCode.isNotEmpty()) { + mHolder.month_day_selected_day_label.text = Formatter.getDateFromCode(activity!!, mSelectedDayCode, false) + } + + activity?.runOnUiThread { + if (activity != null) { + mHolder.month_day_events_list.beVisibleIf(listItems.isNotEmpty()) + mHolder.month_day_no_events_placeholder.beVisibleIf(listItems.isEmpty()) + + val currAdapter = mHolder.month_day_events_list.adapter + if (currAdapter == null) { + EventListAdapter(activity as SimpleActivity, listItems, true, this, month_day_events_list, false) { + if (it is ListEvent) { + activity?.editEvent(it) + } + }.apply { + month_day_events_list.adapter = this + } + } else { + (currAdapter as EventListAdapter).updateListItems(listItems) + } + } } } private fun setupButtons() { - mTextColor = mConfig.textColor - } - - private fun updateDays(days: ArrayList) { - mHolder.month_day_view_wrapper.updateDays(days, false) { -// (activity as MainActivity).openDayFromMonthly(Formatter.getDateTimeFromCode(it.code)) + val textColor = mConfig.textColor + mHolder.apply { + month_day_selected_day_label.setTextColor(textColor) + month_day_no_events_placeholder.setTextColor(textColor) } } fun printCurrentView() {} + + fun getNewEventDayCode() = if (mSelectedDayCode.isEmpty()) mDayCode else mSelectedDayCode + + private fun getMonthLabel(shownMonthDateTime: DateTime): String { + var month = Formatter.getMonthName(activity!!, shownMonthDateTime.monthOfYear) + val targetYear = shownMonthDateTime.toString(YEAR_PATTERN) + if (targetYear != DateTime().toString(YEAR_PATTERN)) { + month += " $targetYear" + } + return month + } + + override fun refreshItems() { + val startDateTime = Formatter.getLocalDateTimeFromCode(mDayCode).minusWeeks(1) + val endDateTime = startDateTime.plusWeeks(6) + activity?.eventsHelper?.getEvents(startDateTime.seconds(), endDateTime.seconds()) { events -> + mListEvents = events + activity?.runOnUiThread { + updateVisibleEvents() + } + } + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt index 81d19bf4a..567e0ad00 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthDayFragmentsHolder.kt @@ -139,7 +139,12 @@ class MonthDayFragmentsHolder : MyFragmentHolder(), NavigationListener { (activity as? MainActivity)?.updateActionBarTitle(getString(R.string.app_launcher_name)) } - override fun getNewEventDayCode() = if (shouldGoToTodayBeVisible()) currentDayCode else todayDayCode + override fun getNewEventDayCode() = (viewPager?.adapter as? MyMonthDayPagerAdapter)?.getNewEventDayCode(viewPager?.currentItem ?: 0) + ?: if (shouldGoToTodayBeVisible()) { + currentDayCode + } else { + todayDayCode + } override fun printView() {} } 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 89ced9500..adfc76663 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 @@ -25,6 +25,8 @@ import com.simplemobiletools.calendar.pro.models.EventWeeklyView import com.simplemobiletools.calendar.pro.views.MyScrollView import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.helpers.DAY_SECONDS +import com.simplemobiletools.commons.helpers.HIGHER_ALPHA +import com.simplemobiletools.commons.helpers.LOWER_ALPHA import com.simplemobiletools.commons.helpers.WEEK_SECONDS import com.simplemobiletools.commons.views.MyTextView import kotlinx.android.synthetic.main.fragment_week.* @@ -449,9 +451,10 @@ class WeekFragment : Fragment(), WeeklyCalendar { val dayColumn = dayColumns[dayOfWeek] (inflater.inflate(R.layout.week_event_marker, null, false) as TextView).apply { var backgroundColor = eventTypeColors.get(event.eventType, primaryColor) - val textColor = backgroundColor.getContrastColor() + var textColor = backgroundColor.getContrastColor() if (dimPastEvents && event.isPastEvent && !isPrintVersion) { - backgroundColor = backgroundColor.adjustAlpha(LOW_ALPHA) + backgroundColor = backgroundColor.adjustAlpha(LOWER_ALPHA) + textColor = textColor.adjustAlpha(HIGHER_ALPHA) } background = ColorDrawable(backgroundColor) @@ -555,9 +558,10 @@ class WeekFragment : Fragment(), WeeklyCalendar { private fun addAllDayEvent(event: Event) { (inflater.inflate(R.layout.week_all_day_event_marker, null, false) as TextView).apply { var backgroundColor = eventTypeColors.get(event.eventType, primaryColor) - val textColor = backgroundColor.getContrastColor() + var textColor = backgroundColor.getContrastColor() if (dimPastEvents && event.isPastEvent && !isPrintVersion) { - backgroundColor = backgroundColor.adjustAlpha(LOW_ALPHA) + backgroundColor = backgroundColor.adjustAlpha(LOWER_ALPHA) + textColor = textColor.adjustAlpha(HIGHER_ALPHA) } background = ColorDrawable(backgroundColor) 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 55a561460..f00ce3da5 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 @@ -13,8 +13,7 @@ import com.simplemobiletools.calendar.pro.extensions.* import com.simplemobiletools.calendar.pro.models.* import com.simplemobiletools.calendar.pro.objects.States.isUpdatingCalDAV import com.simplemobiletools.commons.extensions.* -import com.simplemobiletools.commons.helpers.PERMISSION_READ_CALENDAR -import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_CALENDAR +import com.simplemobiletools.commons.helpers.* import org.joda.time.DateTimeZone import org.joda.time.format.DateTimeFormat import java.util.* @@ -43,6 +42,7 @@ class CalDAVHelper(val context: Context) { fetchCalDAVCalendarEvents(calendar.id, localEventType.id!!, showToasts) } + context.scheduleCalDAVSync(true) callback() } finally { @@ -59,13 +59,13 @@ class CalDAVHelper(val context: Context) { val uri = Calendars.CONTENT_URI val projection = arrayOf( - Calendars._ID, - Calendars.CALENDAR_DISPLAY_NAME, - Calendars.ACCOUNT_NAME, - Calendars.ACCOUNT_TYPE, - Calendars.OWNER_ACCOUNT, - Calendars.CALENDAR_COLOR, - Calendars.CALENDAR_ACCESS_LEVEL) + Calendars._ID, + Calendars.CALENDAR_DISPLAY_NAME, + Calendars.ACCOUNT_NAME, + Calendars.ACCOUNT_TYPE, + Calendars.OWNER_ACCOUNT, + Calendars.CALENDAR_COLOR, + Calendars.CALENDAR_ACCESS_LEVEL) val selection = if (ids.trim().isNotEmpty()) "${Calendars._ID} IN ($ids)" else null context.queryCursor(uri, projection, selection, showErrors = showToasts) { cursor -> @@ -83,39 +83,38 @@ class CalDAVHelper(val context: Context) { return calendars } + // check if the calendars color or title has changed fun updateCalDAVCalendar(eventType: EventType) { val uri = Calendars.CONTENT_URI - val values = fillCalendarContentValues(eventType) val newUri = ContentUris.withAppendedId(uri, eventType.caldavCalendarId.toLong()) - try { - context.contentResolver.update(newUri, values, null, null) - } catch (e: IllegalArgumentException) { - } - } + val projection = arrayOf( + Calendars.CALENDAR_COLOR_KEY, + Calendars.CALENDAR_COLOR, + Calendars.CALENDAR_DISPLAY_NAME + ) - private fun fillCalendarContentValues(eventType: EventType): ContentValues { - val colorKey = getEventTypeColorKey(eventType) - return ContentValues().apply { - put(Calendars.CALENDAR_COLOR_KEY, colorKey) - put(Calendars.CALENDAR_DISPLAY_NAME, eventType.title) - } - } - - @SuppressLint("MissingPermission") - private fun getEventTypeColorKey(eventType: EventType): Int { - val uri = Colors.CONTENT_URI - val projection = arrayOf(Colors.COLOR_KEY) - val selection = "${Colors.COLOR_TYPE} = ? AND ${Colors.COLOR} = ? AND ${Colors.ACCOUNT_NAME} = ?" - val selectionArgs = arrayOf(Colors.TYPE_CALENDAR.toString(), eventType.color.toString(), eventType.caldavEmail) - - val cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null) - cursor?.use { - if (cursor.moveToFirst()) { - return cursor.getStringValue(Colors.COLOR_KEY).toInt() + context.queryCursor(newUri, projection) { cursor -> + val properColorKey = cursor.getIntValue(Calendars.CALENDAR_COLOR_KEY) + val properColor = cursor.getIntValue(Calendars.CALENDAR_COLOR) + val displayName = cursor.getStringValue(Calendars.CALENDAR_DISPLAY_NAME) + if (eventType.color != properColor || displayName != eventType.title) { + val values = fillCalendarContentValues(properColorKey, displayName) + try { + context.contentResolver.update(newUri, values, null, null) + eventType.color = properColor + eventType.title = displayName + context.eventTypesDB.insertOrUpdate(eventType) + } catch (e: IllegalArgumentException) { + } } } + } - return -1 + private fun fillCalendarContentValues(colorKey: Int, title: String): ContentValues { + return ContentValues().apply { + put(Calendars.CALENDAR_COLOR_KEY, colorKey) + put(Calendars.CALENDAR_DISPLAY_NAME, title) + } } @SuppressLint("MissingPermission") @@ -157,21 +156,21 @@ class CalDAVHelper(val context: Context) { val uri = Events.CONTENT_URI val projection = arrayOf( - Events._ID, - Events.TITLE, - Events.DESCRIPTION, - Events.DTSTART, - Events.DTEND, - Events.DURATION, - Events.EXDATE, - Events.ALL_DAY, - Events.RRULE, - Events.ORIGINAL_ID, - Events.ORIGINAL_INSTANCE_TIME, - Events.EVENT_LOCATION, - Events.EVENT_TIMEZONE, - Events.CALENDAR_TIME_ZONE, - Events.DELETED) + Events._ID, + Events.TITLE, + Events.DESCRIPTION, + Events.DTSTART, + Events.DTEND, + Events.DURATION, + Events.EXDATE, + Events.ALL_DAY, + Events.RRULE, + Events.ORIGINAL_ID, + Events.ORIGINAL_INSTANCE_TIME, + Events.EVENT_LOCATION, + Events.EVENT_TIMEZONE, + Events.CALENDAR_TIME_ZONE, + Events.DELETED) val selection = "${Events.CALENDAR_ID} = $calendarId" context.queryCursor(uri, projection, selection, showErrors = showToasts) { cursor -> @@ -203,15 +202,15 @@ class CalDAVHelper(val context: Context) { val reminder3 = reminders.getOrNull(2) val importId = getCalDAVEventImportId(calendarId, id) val eventTimeZone = cursor.getStringValue(Events.EVENT_TIMEZONE) - ?: cursor.getStringValue(Events.CALENDAR_TIME_ZONE) ?: DateTimeZone.getDefault().id + ?: cursor.getStringValue(Events.CALENDAR_TIME_ZONE) ?: DateTimeZone.getDefault().id val source = "$CALDAV-$calendarId" val repeatRule = Parser().parseRepeatInterval(rrule, startTS) val event = Event(null, startTS, endTS, title, location, description, reminder1?.minutes ?: REMINDER_OFF, - reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type - ?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type - ?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule, - repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, source = source) + reminder2?.minutes ?: REMINDER_OFF, reminder3?.minutes ?: REMINDER_OFF, reminder1?.type + ?: REMINDER_NOTIFICATION, reminder2?.type ?: REMINDER_NOTIFICATION, reminder3?.type + ?: REMINDER_NOTIFICATION, repeatRule.repeatInterval, repeatRule.repeatRule, + repeatRule.repeatLimit, ArrayList(), attendees, importId, eventTimeZone, allDay, eventTypeId, source = source) if (event.getIsAllDay()) { event.startTS = Formatter.getShiftedImportTimestamp(event.startTS) @@ -241,12 +240,13 @@ class CalDAVHelper(val context: Context) { } // some calendars add repeatable event exceptions with using the "exdate" field, not by creating a child event that is an exception + // exdate can be stored as "20190216T230000Z", but also as "Europe/Madrid;20201208T000000Z" val exdate = cursor.getStringValue(Events.EXDATE) ?: "" if (exdate.length > 8) { val lines = exdate.split("\n") for (line in lines) { val dates = line.split(",") - dates.forEach { + dates.filter { it.isNotEmpty() && it[0].isDigit() }.forEach { if (it.endsWith("Z")) { // convert for example "20190216T230000Z" to "20190217000000" in Slovakia in a weird way val formatter = DateTimeFormat.forPattern("yyyyMMdd'T'HHmmss'Z'") @@ -469,8 +469,8 @@ class CalDAVHelper(val context: Context) { val reminders = ArrayList() val uri = Reminders.CONTENT_URI val projection = arrayOf( - Reminders.MINUTES, - Reminders.METHOD) + Reminders.MINUTES, + Reminders.METHOD) val selection = "${Reminders.EVENT_ID} = $eventId" context.queryCursor(uri, projection, selection) { cursor -> @@ -490,10 +490,10 @@ class CalDAVHelper(val context: Context) { val attendees = ArrayList() val uri = Attendees.CONTENT_URI val projection = arrayOf( - Attendees.ATTENDEE_NAME, - Attendees.ATTENDEE_EMAIL, - Attendees.ATTENDEE_STATUS, - Attendees.ATTENDEE_RELATIONSHIP) + Attendees.ATTENDEE_NAME, + Attendees.ATTENDEE_EMAIL, + Attendees.ATTENDEE_STATUS, + Attendees.ATTENDEE_RELATIONSHIP) val selection = "${Attendees.EVENT_ID} = $eventId" context.queryCursor(uri, projection, selection) { cursor -> val name = cursor.getStringValue(Attendees.ATTENDEE_NAME) ?: "" diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt index baba181e3..020b69644 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/Constants.kt @@ -1,8 +1,8 @@ package com.simplemobiletools.calendar.pro.helpers -const val LOW_ALPHA = .3f -const val MEDIUM_ALPHA = .6f const val STORED_LOCALLY_ONLY = 0 +const val ROW_COUNT = 6 +const val COLUMN_COUNT = 7 const val DAY_CODE = "day_code" const val YEAR_LABEL = "year" @@ -163,8 +163,8 @@ fun getNowSeconds() = System.currentTimeMillis() / 1000L fun isWeekend(i: Int, isSundayFirst: Boolean): Boolean { return if (isSundayFirst) { - i == 0 || i == 6 + i == 0 || i == 6 || i == 7 || i == 13 } else { - i == 5 || i == 6 + i == 5 || i == 6 || i == 12 || i == 13 } } 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 a837e72c9..765021b96 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 @@ -73,7 +73,7 @@ class IcsImporter(val activity: SimpleActivity) { continue } - if (line == BEGIN_EVENT) { + if (line.trim() == BEGIN_EVENT) { resetValues() curEventTypeId = defaultEventTypeId isParsingEvent = true @@ -134,7 +134,13 @@ class IcsImporter(val activity: SimpleActivity) { value = value.substring(0, value.length - 1) } - curRepeatExceptions.add(Formatter.getDayCodeFromTS(getTimestamp(value))) + if (value.contains(",")) { + value.split(",").forEach { exdate -> + curRepeatExceptions.add(Formatter.getDayCodeFromTS(getTimestamp(exdate))) + } + } else { + curRepeatExceptions.add(Formatter.getDayCodeFromTS(getTimestamp(value))) + } } else if (line.startsWith(LOCATION)) { curLocation = getLocation(line.substring(LOCATION.length).replace("\\,", ",")) if (curLocation.trim().isEmpty()) { @@ -145,14 +151,15 @@ class IcsImporter(val activity: SimpleActivity) { curRecurrenceDayCode = Formatter.getDayCodeFromTS(timestamp) } else if (line.startsWith(SEQUENCE)) { isSequence = true - } else if (line == BEGIN_ALARM) { + } else if (line.trim() == BEGIN_ALARM) { isNotificationDescription = true - } else if (line == END_ALARM) { + } else if (line.trim() == END_ALARM) { if (isProperReminderAction && curReminderTriggerMinutes != REMINDER_OFF) { curReminderMinutes.add(curReminderTriggerMinutes) curReminderActions.add(curReminderTriggerAction) } - } else if (line == END_EVENT) { + isNotificationDescription = false + } else if (line.trim() == END_EVENT) { isParsingEvent = false if (curStart != -1L && curEnd == -1L) { curEnd = curStart @@ -246,17 +253,19 @@ class IcsImporter(val activity: SimpleActivity) { private fun getTimestamp(fullString: String): Long { return try { - if (fullString.startsWith(';')) { - val value = fullString.substring(fullString.lastIndexOf(':') + 1).replace(" ", "") - if (value.isEmpty()) { - return 0 - } else if (!value.contains("T")) { - curFlags = curFlags or FLAG_ALL_DAY - } + when { + fullString.startsWith(';') -> { + val value = fullString.substring(fullString.lastIndexOf(':') + 1).replace(" ", "") + if (value.isEmpty()) { + return 0 + } else if (!value.contains("T")) { + curFlags = curFlags or FLAG_ALL_DAY + } - Parser().parseDateTimeValue(value) - } else { - Parser().parseDateTimeValue(fullString.substring(1)) + Parser().parseDateTimeValue(value) + } + fullString.startsWith(":") -> Parser().parseDateTimeValue(fullString.substring(1)) + else -> Parser().parseDateTimeValue(fullString) } } catch (e: Exception) { activity.showErrorToast(e) 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 ebda2b729..fc456a3f2 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 @@ -18,6 +18,7 @@ import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA import org.joda.time.DateTime class MyWidgetMonthlyProvider : AppWidgetProvider() { diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt index d6d45abb5..123a197e6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/jobs/CalDAVUpdateListener.kt @@ -10,9 +10,7 @@ import android.content.Context import android.os.Build import android.os.Handler import android.provider.CalendarContract -import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.recheckCalDAVCalendars -import com.simplemobiletools.calendar.pro.extensions.refreshCalDAVCalendars // based on https://developer.android.com/reference/android/app/job/JobInfo.Builder.html#addTriggerContentUri(android.app.job.JobInfo.TriggerContentUri) @TargetApi(Build.VERSION_CODES.N) @@ -34,13 +32,13 @@ class CalDAVUpdateListener : JobService() { val uri = CalendarContract.Calendars.CONTENT_URI JobInfo.Builder(CALDAV_EVENT_CONTENT_JOB, componentName).apply { addTriggerContentUri(JobInfo.TriggerContentUri(uri, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)) - context.getSystemService(JobScheduler::class.java).schedule(build()) + (context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler).schedule(build()) } } fun isScheduled(context: Context): Boolean { val jobScheduler = context.getSystemService(JobScheduler::class.java) - val jobs = jobScheduler.allPendingJobs ?: return false + val jobs = jobScheduler.allPendingJobs return jobs.any { it.id == CALDAV_EVENT_CONTENT_JOB } } 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 8ed5898ac..3f2febe65 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 @@ -99,10 +99,8 @@ data class Event( private fun addXthDayInterval(currStart: DateTime, original: Event, forceLastWeekday: Boolean): DateTime { val day = currStart.dayOfWeek var order = (currStart.dayOfMonth - 1) / 7 - val properMonth = currStart.withDayOfMonth(7).plusMonths(repeatInterval / MONTH).withDayOfWeek(day) - var firstProperDay = properMonth.dayOfMonth % 7 - if (firstProperDay == 0) - firstProperDay = properMonth.dayOfMonth + var properMonth = currStart.withDayOfMonth(7).plusMonths(repeatInterval / MONTH).withDayOfWeek(day) + var wantedDay: Int // check if it should be for example Fourth Monday, or Last Monday if (forceLastWeekday && (order == 3 || order == 4)) { @@ -112,13 +110,14 @@ data class Event( order = -1 } - val daysCnt = properMonth.dayOfMonth().maximumValue - var wantedDay = firstProperDay + order * 7 - if (wantedDay > daysCnt) - wantedDay -= 7 - if (order == -1) { - wantedDay = firstProperDay + ((daysCnt - firstProperDay) / 7) * 7 + wantedDay = properMonth.dayOfMonth + ((properMonth.dayOfMonth().maximumValue - properMonth.dayOfMonth) / 7) * 7 + } else { + wantedDay = properMonth.dayOfMonth + (order - (properMonth.dayOfMonth - 1) / 7) * 7 + while (properMonth.dayOfMonth().maximumValue < wantedDay) { + properMonth = properMonth.withDayOfMonth(7).plusMonths(repeatInterval / MONTH).withDayOfWeek(day) + wantedDay = properMonth.dayOfMonth + (order - (properMonth.dayOfMonth - 1) / 7) * 7 + } } return properMonth.withDayOfMonth(wantedDay) 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 0d6b229d5..b63d83475 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 @@ -1,9 +1,7 @@ package com.simplemobiletools.calendar.pro.views import android.content.Context -import android.graphics.Canvas -import android.graphics.Paint -import android.graphics.RectF +import android.graphics.* import android.text.TextPaint import android.text.TextUtils import android.util.AttributeSet @@ -12,10 +10,7 @@ import android.view.View import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config import com.simplemobiletools.calendar.pro.extensions.seconds -import com.simplemobiletools.calendar.pro.helpers.Formatter -import com.simplemobiletools.calendar.pro.helpers.LOW_ALPHA -import com.simplemobiletools.calendar.pro.helpers.MEDIUM_ALPHA -import com.simplemobiletools.calendar.pro.helpers.isWeekend +import com.simplemobiletools.calendar.pro.helpers.* import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.calendar.pro.models.Event import com.simplemobiletools.calendar.pro.models.MonthViewEvent @@ -23,17 +18,20 @@ import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor import com.simplemobiletools.commons.extensions.getContrastColor import com.simplemobiletools.commons.extensions.moveLastItemToFront +import com.simplemobiletools.commons.helpers.HIGHER_ALPHA +import com.simplemobiletools.commons.helpers.LOWER_ALPHA +import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA import org.joda.time.DateTime import org.joda.time.Days // used in the Monthly view fragment, 1 view per screen class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(context, attrs, defStyle) { private val BG_CORNER_RADIUS = 8f - private val ROW_COUNT = 6 private var textPaint: Paint private var eventTitlePaint: TextPaint private var gridPaint: Paint + private var circleStrokePaint: Paint private var config = context.config private var dayWidth = 0f private var dayHeight = 0f @@ -53,9 +51,11 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con private var isMonthDayView = false private var allEvents = ArrayList() private var bgRectF = RectF() + private var dayTextRect = Rect() private var dayLetters = ArrayList() private var days = ArrayList() private var dayVerticalOffsets = SparseIntArray() + private var selectedDayCoords = Point(-1, -1) constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0) @@ -78,7 +78,13 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con } gridPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { - color = textColor.adjustAlpha(LOW_ALPHA) + color = textColor.adjustAlpha(LOWER_ALPHA) + } + + circleStrokePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { + style = Paint.Style.STROKE + strokeWidth = resources.getDimension(R.dimen.circle_stroke_width) + color = primaryColor } val smallerTextSize = resources.getDimensionPixelSize(R.dimen.smaller_text_size) @@ -142,7 +148,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con var curId = 0 for (y in 0 until ROW_COUNT) { - for (x in 0..6) { + for (x in 0 until COLUMN_COUNT) { val day = days.getOrNull(curId) if (day != null) { dayVerticalOffsets.put(day.indexOnMonthView, dayVerticalOffsets[day.indexOnMonthView] + weekDaysLetterHeight) @@ -150,11 +156,26 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con val xPos = x * dayWidth + horizontalOffset val yPos = y * dayHeight + verticalOffset val xPosCenter = xPos + dayWidth / 2 - if (day.isToday && !isPrintVersion) { - canvas.drawCircle(xPosCenter, yPos + textPaint.textSize * 0.7f, textPaint.textSize * 0.75f, getCirclePaint(day)) + val dayNumber = day.value.toString() + + val textPaint = getTextPaint(day) + if (selectedDayCoords.x != -1 && x == selectedDayCoords.x && y == selectedDayCoords.y) { + canvas.drawCircle(xPosCenter, yPos + textPaint.textSize * 0.7f, textPaint.textSize * 0.8f, circleStrokePaint) + if (day.isToday) { + textPaint.color = textColor + } + } else if (day.isToday && !isPrintVersion) { + canvas.drawCircle(xPosCenter, yPos + textPaint.textSize * 0.7f, textPaint.textSize * 0.8f, getCirclePaint(day)) } - canvas.drawText(day.value.toString(), xPosCenter, yPos + textPaint.textSize, getTextPaint(day)) + // mark days with events with a dot + if (isMonthDayView && day.dayEvents.isNotEmpty()) { + getCirclePaint(day).getTextBounds(dayNumber, 0, dayNumber.length, dayTextRect) + val height = dayTextRect.height() * 1.25f + canvas.drawCircle(xPosCenter, yPos + height + textPaint.textSize / 2, textPaint.textSize * 0.2f, getDayEventColor(day.dayEvents.first())) + } + + canvas.drawText(dayNumber, xPosCenter, yPos + textPaint.textSize, textPaint) dayVerticalOffsets.put(day.indexOnMonthView, (verticalOffset + textPaint.textSize * 2).toInt()) } curId++ @@ -170,7 +191,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con private fun drawGrid(canvas: Canvas) { // vertical lines - for (i in 0..6) { + for (i in 0 until COLUMN_COUNT) { var lineX = i * dayWidth if (showWeekNumbers) { lineX += horizontalOffset @@ -180,13 +201,13 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con // horizontal lines canvas.drawLine(0f, 0f, canvas.width.toFloat(), 0f, gridPaint) - for (i in 0..5) { + for (i in 0 until ROW_COUNT) { canvas.drawLine(0f, i * dayHeight + weekDaysLetterHeight, canvas.width.toFloat(), i * dayHeight + weekDaysLetterHeight, gridPaint) } } private fun addWeekDayLetters(canvas: Canvas) { - for (i in 0..6) { + for (i in 0 until COLUMN_COUNT) { val xPos = horizontalOffset + (i + 1) * dayWidth - dayWidth / 2 var weekDayLetterPaint = textPaint if (i == currDayOfWeek && !isPrintVersion) { @@ -231,7 +252,9 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con val xPosCenter = xPos + dayWidth / 2 if (verticalOffset - eventTitleHeight * 2 > dayHeight) { - canvas.drawText("...", xPosCenter, yPos + verticalOffset - eventTitleHeight / 2, getTextPaint(days[event.startDayIndex])) + val paint = getTextPaint(days[event.startDayIndex]) + paint.color = textColor + canvas.drawText("...", xPosCenter, yPos + verticalOffset - eventTitleHeight / 2, paint) return } @@ -255,16 +278,16 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con bgRectF.set(bgLeft, bgTop, bgRight, bgBottom) canvas.drawRoundRect(bgRectF, BG_CORNER_RADIUS, BG_CORNER_RADIUS, getEventBackgroundColor(event, startDayIndex, endDayIndex)) - drawEventTitle(event, canvas, xPos, yPos + verticalOffset, bgRight - bgLeft - smallPadding) + drawEventTitle(event, canvas, xPos, yPos + verticalOffset, bgRight - bgLeft - smallPadding, startDayIndex, endDayIndex) for (i in 0 until Math.min(event.daysCnt, 7 - event.startDayIndex % 7)) { dayVerticalOffsets.put(event.startDayIndex + i, verticalOffset + eventTitleHeight + smallPadding * 2) } } - private fun drawEventTitle(event: MonthViewEvent, canvas: Canvas, x: Float, y: Float, availableWidth: Float) { + private fun drawEventTitle(event: MonthViewEvent, canvas: Canvas, x: Float, y: Float, availableWidth: Float, startDay: DayMonthly, endDay: DayMonthly) { val ellipsized = TextUtils.ellipsize(event.title, eventTitlePaint, availableWidth - smallPadding, TextUtils.TruncateAt.END) - canvas.drawText(event.title, 0, ellipsized.length, x + smallPadding * 2, y, getEventTitlePaint(event)) + canvas.drawText(event.title, 0, ellipsized.length, x + smallPadding * 2, y, getEventTitlePaint(event, startDay, endDay)) } private fun getTextPaint(startDay: DayMonthly): Paint { @@ -299,9 +322,14 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con return getColoredPaint(paintColor) } - private fun getEventTitlePaint(event: MonthViewEvent): Paint { + private fun getEventTitlePaint(event: MonthViewEvent, startDay: DayMonthly, endDay: DayMonthly): Paint { + var paintColor = event.color.getContrastColor() + if ((!startDay.isThisMonth && !endDay.isThisMonth) || (dimPastEvents && event.isPastEvent && !isPrintVersion)) { + paintColor = paintColor.adjustAlpha(HIGHER_ALPHA) + } + val curPaint = Paint(eventTitlePaint) - curPaint.color = event.color.getContrastColor() + curPaint.color = paintColor return curPaint } @@ -315,6 +343,12 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con return curPaint } + private fun getDayEventColor(event: Event): Paint { + val curPaint = Paint(Paint.ANTI_ALIAS_FLAG) + curPaint.color = event.color + return curPaint + } + private fun initWeekDayLetters() { dayLetters = context.resources.getStringArray(R.array.week_day_letters).toMutableList() as ArrayList if (config.isSundayFirst) { @@ -369,8 +403,13 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con } textPaint.color = textColor - gridPaint.color = textColor.adjustAlpha(LOW_ALPHA) + gridPaint.color = textColor.adjustAlpha(LOWER_ALPHA) invalidate() initWeekDayLetters() } + + fun updateCurrentlySelectedDay(x: Int, y: Int) { + selectedDayCoords = Point(x, y) + invalidate() + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthViewWrapper.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthViewWrapper.kt index 187b6bd86..3712013d2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthViewWrapper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthViewWrapper.kt @@ -6,6 +6,8 @@ import android.view.LayoutInflater import android.widget.FrameLayout import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config +import com.simplemobiletools.calendar.pro.helpers.COLUMN_COUNT +import com.simplemobiletools.calendar.pro.helpers.ROW_COUNT import com.simplemobiletools.calendar.pro.models.DayMonthly import com.simplemobiletools.commons.extensions.onGlobalLayout import kotlinx.android.synthetic.main.month_view.view.* @@ -36,7 +38,7 @@ class MonthViewWrapper(context: Context, attrs: AttributeSet, defStyle: Int) : F onGlobalLayout { if (!wereViewsAdded && days.isNotEmpty()) { measureSizes() - addViews() + addClickableBackgrounds() monthView.updateDays(days, isMonthDayView) } } @@ -48,7 +50,7 @@ class MonthViewWrapper(context: Context, attrs: AttributeSet, defStyle: Int) : F dayClickCallback = callback days = newDays if (dayWidth != 0f && dayHeight != 0f) { - addViews() + addClickableBackgrounds() } isMonthDayView = !addEvents @@ -69,32 +71,41 @@ class MonthViewWrapper(context: Context, attrs: AttributeSet, defStyle: Int) : F } } - private fun addViews() { + private fun addClickableBackgrounds() { removeAllViews() monthView = inflater.inflate(R.layout.month_view, this).month_view wereViewsAdded = true var curId = 0 - for (y in 0..5) { - for (x in 0..6) { + for (y in 0 until ROW_COUNT) { + for (x in 0 until COLUMN_COUNT) { val day = days.getOrNull(curId) if (day != null) { - val xPos = x * dayWidth + horizontalOffset - val yPos = y * dayHeight + weekDaysLetterHeight - addViewBackground(xPos, yPos, day) + addViewBackground(x, y, day) } curId++ } } } - private fun addViewBackground(xPos: Float, yPos: Float, day: DayMonthly) { + private fun addViewBackground(viewX: Int, viewY: Int, day: DayMonthly) { + val xPos = viewX * dayWidth + horizontalOffset + val yPos = viewY * dayHeight + weekDaysLetterHeight + inflater.inflate(R.layout.month_view_background, this, false).apply { + if (isMonthDayView) { + background = null + } + layoutParams.width = dayWidth.toInt() layoutParams.height = dayHeight.toInt() x = xPos y = yPos setOnClickListener { dayClickCallback?.invoke(day) + + if (isMonthDayView) { + monthView.updateCurrentlySelectedDay(viewX, viewY) + } } addView(this) } diff --git a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt index f17072f58..ee8e37d09 100644 --- a/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/SmallMonthView.kt @@ -8,11 +8,11 @@ import android.util.AttributeSet import android.view.View import com.simplemobiletools.calendar.pro.R import com.simplemobiletools.calendar.pro.extensions.config -import com.simplemobiletools.calendar.pro.helpers.MEDIUM_ALPHA import com.simplemobiletools.calendar.pro.helpers.isWeekend import com.simplemobiletools.calendar.pro.models.DayYearly import com.simplemobiletools.commons.extensions.adjustAlpha import com.simplemobiletools.commons.extensions.getAdjustedPrimaryColor +import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA import java.util.* // used for displaying months at Yearly view diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index fc2f5110b..f7b2940d8 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -32,6 +32,27 @@ + + + + + + - + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@+id/month_day_list_holder" + app:layout_constraintHeight_percent="0.3" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> - + + + + + + + + + + + + diff --git a/app/src/main/res/layout/month_view.xml b/app/src/main/res/layout/month_view.xml index 4e2e595b5..5a861eaf2 100644 --- a/app/src/main/res/layout/month_view.xml +++ b/app/src/main/res/layout/month_view.xml @@ -1,6 +1,5 @@ - + android:layout_height="match_parent" /> diff --git a/app/src/main/res/layout/month_view_background.xml b/app/src/main/res/layout/month_view_background.xml index f7eb272d5..e9fad9058 100644 --- a/app/src/main/res/layout/month_view_background.xml +++ b/app/src/main/res/layout/month_view_background.xml @@ -1,7 +1,6 @@ - + android:background="?attr/selectableItemBackground" /> diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2b4b999cd..82cddc031 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -71,6 +71,7 @@ ثاني ثالث رابع + fifth أخير @@ -81,6 +82,7 @@ ثاني ثالث رابع + fifth أخير diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index 287e767a5..70a213a04 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -71,6 +71,7 @@ ikinci üçüncü dördüncü + fifth sonuncu @@ -81,6 +82,7 @@ ikinci üçüncü dördüncü + fifth sonuncu diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index f6884cac7..af5c64e54 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -75,6 +75,7 @@ দ্বিতীয় তৃতীয় চতুর্থ + fifth শেষ @@ -85,6 +86,7 @@ দ্বিতীয় তৃতীয় চতুর্থ + fifth শেষ diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml index 977154bb1..9e0869d3a 100644 --- a/app/src/main/res/values-br/strings.xml +++ b/app/src/main/res/values-br/strings.xml @@ -71,6 +71,7 @@ eil trede pevare + fifth diwezhañ @@ -81,6 +82,7 @@ eil trede pevare + fifth diwezhañ diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index c9b6489e0..27a7c9311 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -71,6 +71,7 @@ druhý třetí čtvrtý + fifth poslední @@ -81,6 +82,7 @@ druhou třetí čtvrtou + fifth poslední diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index b5b3fab86..49ebe310d 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -71,6 +71,7 @@ anden tredje fjerde + fifth sidste @@ -81,6 +82,7 @@ anden tredje fjerde + fifth sidste diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2c3898598..8122247b8 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -71,6 +71,7 @@ zweiten dritten vierten + fifth letzten @@ -81,6 +82,7 @@ zweiten dritten vierten + fifth letzten diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index f033eb6d6..99f1f6ba9 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -71,6 +71,7 @@ δεύτερη τρίτη τέταρτη + fifth τελευταία @@ -81,6 +82,7 @@ δεύτερη τρίτη τέταρτη + fifth τελευταία diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 07a20ee7b..674edf05c 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -71,6 +71,7 @@ segundo tercero cuarto + fifth último @@ -81,6 +82,7 @@ segundo tercer cuarto + fifth último diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 45d3e031f..1469b2ac8 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -71,6 +71,7 @@ bigarren hirugarren laugarren + fifth azken @@ -81,6 +82,7 @@ bigarren hirugarren laugarren + fifth azken diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index f7e7bc1bd..ef0902208 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -71,6 +71,7 @@ toinen kolmas neljäs + fifth viimeinen @@ -81,6 +82,7 @@ toisena kolmantena neljäntenä + fifth viimeisenä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f46be900b..de592efa2 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -72,6 +72,7 @@ deuxième troisième quatrième + fifth dernier @@ -82,6 +83,7 @@ deuxième troisième quatrième + fifth dernier diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 8fd78d709..9598753cd 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -71,6 +71,7 @@ segundo terceiro cuarto + fifth último @@ -81,6 +82,7 @@ segundo terceiro cuarto + fifth último diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml index 3a5d44af5..483d103a6 100644 --- a/app/src/main/res/values-he/strings.xml +++ b/app/src/main/res/values-he/strings.xml @@ -71,6 +71,7 @@ שני שלישי רביעי + fifth אחרון @@ -81,6 +82,7 @@ שניה שלישית רביעית + fifth אחרונה diff --git a/app/src/main/res/values-hi-rIN/strings.xml b/app/src/main/res/values-hi-rIN/strings.xml index bbbe2ed5f..6a762ad92 100644 --- a/app/src/main/res/values-hi-rIN/strings.xml +++ b/app/src/main/res/values-hi-rIN/strings.xml @@ -71,6 +71,7 @@ second third fourth + fifth last @@ -81,6 +82,7 @@ second third fourth + fifth last diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index cb0db7c0c..d0c959272 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -71,6 +71,7 @@ drugi treći četvrti + fifth peti @@ -81,6 +82,7 @@ drugi treći četvrti + fifth peti diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 18ef34027..aad876d21 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -71,6 +71,7 @@ second third fourth + fifth last @@ -81,6 +82,7 @@ second third fourth + fifth last diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 8fe9ea8b8..100c7c96b 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -71,6 +71,7 @@ kedua ketiga keempat + fifth terakhir @@ -81,6 +82,7 @@ kedua ketiga keempat + fifth terakhir diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 8fe9ea8b8..100c7c96b 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -71,6 +71,7 @@ kedua ketiga keempat + fifth terakhir @@ -81,6 +82,7 @@ kedua ketiga keempat + fifth terakhir diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 6cfda87ad..6badf2385 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -71,6 +71,7 @@ secondo terzo quarto + fifth ultimo @@ -81,6 +82,7 @@ secondo terzo quarto + fifth ultimo diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 96f5da76d..432cb0aea 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -71,6 +71,7 @@ שני שלישי רביעי + fifth אחרון @@ -81,6 +82,7 @@ שניה שלישית רביעית + fifth אחרונה diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 6d5ce371a..ba0f3f373 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -71,6 +71,7 @@ second third fourth + fifth last @@ -81,6 +82,7 @@ second third fourth + fifth last diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index ef2fa5447..8238e4b35 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -71,6 +71,7 @@ 두 번째 세 번째 네 번째 + fifth 마지막 @@ -81,6 +82,7 @@ 두 번째 세 번째 네 번째 + fifth 마지막 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 27a10430d..8c4b5348b 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -71,6 +71,7 @@ Antrą Trečią Ketvirtą + fifth Paskutinę @@ -81,6 +82,7 @@ Antrą Trečią Ketvirtą + fifth Paskutinę diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 7e40b6a80..4badfcba7 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -71,6 +71,7 @@ 2. 3. 4. + fifth pēdēj. @@ -81,6 +82,7 @@ 2. 3. 4. + fifth pēdēj. diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 248fb1405..0d6b02bb2 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -71,6 +71,7 @@ andre tredje fjerde + fifth siste @@ -81,6 +82,7 @@ andre tredje fjerde + fifth siste diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 78ef5ea29..fe54a8b35 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -71,6 +71,7 @@ tweede derde vierde + vijfde laatste @@ -81,6 +82,7 @@ tweede derde vierde + vijfde laatste diff --git a/app/src/main/res/values-no/strings.xml b/app/src/main/res/values-no/strings.xml index 8b0438676..2d774fbf4 100644 --- a/app/src/main/res/values-no/strings.xml +++ b/app/src/main/res/values-no/strings.xml @@ -71,6 +71,7 @@ andre tredje fjerde + fifth siste @@ -81,6 +82,7 @@ andre tredje fjerde + fifth siste diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a3f51bd8b..0e1920a66 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -71,6 +71,7 @@ drugi(ą) trzeci(ą) czwarty(ą) + fifth ostatni(ą) @@ -81,6 +82,7 @@ drugi(ą) trzeci(ą) czwarty(ą) + fifth ostatni(ą) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index aa80126f2..93d2155b5 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -71,6 +71,7 @@ segundo terceiro quarto + fifth último @@ -81,6 +82,7 @@ segundo terceiro quarto + fifth ultimo diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 127b1e7c3..f7d81f6f1 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -6,10 +6,10 @@ Vista diária Vista semanal Vista mensal - Monthly + daily view + Mensal + vista diária Vista anual Lista de eventos - Parece que você não tem eventos para breve + Parece que não existem eventos para breve Ir para hoje Ir para data Olá,\n\nparece que você utilizou a opção de atualização existente na versão antiga. Tem que migrar os eventos locais através de exportação para um ficheiro .ics e posterior importação. Pode encontrar os botões de exportação/importação no ecrã do menu principal.\n\nDepois já poderá desinstalar a aplicação antiga. Também terá que repor as predefinições da aplicação.\n\nObrigado! @@ -71,6 +71,7 @@ segunda terceira quarta + fifth última @@ -81,6 +82,7 @@ segundo terceiro quarto + fifth último @@ -144,7 +146,7 @@ Selecione um tipo de evento Mover eventos afetados para o tipo de evento padrão Remover permanentemente os eventos afetados - Para remover um calendário CalDAV, tem que cancelar a sua sincronização + Para remover um calendário CalDAV, tem que cancelar a sincronização Feriados diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 5e0180173..7306dc38e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -71,6 +71,7 @@ a doua a treia a patra + fifth ultima @@ -81,6 +82,7 @@ a doua a treia a patra + fifth ultima diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 2133e6917..487378018 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -71,6 +71,7 @@ второй третий четвёртый + fifth последний @@ -81,6 +82,7 @@ вторую третью четвёртую + fifth последнюю diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index c5117e19e..f1de7b292 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -71,6 +71,7 @@ druhý tretí štvrtý + piaty posledný @@ -81,6 +82,7 @@ druhú tretiu štvrtú + piatu poslednú diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index ac52f9fd0..00f8b6e56 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -71,6 +71,7 @@ andra tredje fjärde + fifth sista @@ -81,6 +82,7 @@ andra tredje fjärde + fifth sista diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 5ec245c53..c4b0e3f7c 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -71,6 +71,7 @@ ikinci üçüncü dördüncü + fifth son @@ -81,6 +82,7 @@ ikinci üçüncü dördüncü + fifth son diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 4a12eebd2..e07d920e1 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -71,6 +71,7 @@ другий третій четвертий + fifth останній @@ -81,6 +82,7 @@ другий третій четвертий + fifth останній diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d75222e11..389dcb0c4 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -71,6 +71,7 @@     第二个     第三个     第四个 + fifth     最后的      @@ -81,6 +82,7 @@     第二个     第三个     第四个 + fifth     最后的      diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 41c217dc8..1e5edc8f6 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -71,6 +71,7 @@ 第二個 第三個 第四個 + fifth 最後的 @@ -81,6 +82,7 @@ 第二個 第三個 第四個 + fifth 最後的 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 93c090198..1c0c00a76 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -71,6 +71,7 @@ 第二個 第三個 第四個 + fifth 最後的 @@ -81,6 +82,7 @@ 第二個 第三個 第四個 + fifth 最後的 diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 221830c09..a8d9190b4 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -3,6 +3,7 @@ 10dp 3dp 6dp + 2dp 40dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aec412c77..745853f80 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,6 +71,7 @@ second third fourth + fifth last @@ -81,6 +82,7 @@ second third fourth + fifth last diff --git a/build.gradle b/build.gradle index ce2f58d09..0ea14ab23 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.4.30' + ext.kotlin_version = '1.4.31' repositories { google() diff --git a/fastlane/metadata/android/en-US/changelogs/192.txt b/fastlane/metadata/android/en-US/changelogs/192.txt new file mode 100644 index 000000000..18dcc0aeb --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/192.txt @@ -0,0 +1,6 @@ + * Added a new combination of monthly + daily view + * Fixed too big background activity with CalDAV sync enabled + * Fixed some glitches at importing .ics files + * Fixed a glitch at new events having wrong date set by default in some cases + * Added a setting item for quick notification customizing on Android 8+ + * Added some translation and stability improvements diff --git a/fastlane/metadata/android/en-US/changelogs/193.txt b/fastlane/metadata/android/en-US/changelogs/193.txt new file mode 100644 index 000000000..3d1732ed6 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/193.txt @@ -0,0 +1,3 @@ + * Allow repeating events every fifth weekday + * Properly highlight weekends on widgets, if selected so + * Fixed some CalDAV syncing and .ics file importing issues