Compare commits

...

4 Commits

Author SHA1 Message Date
elmuffo a1da71d3e1
Swipe to snooze (#2839) 1 month ago
Alex Baker c793a300cc Add preference summary 1 month ago
Ilya Bizyaev bf84bf9e82 [Feature] Add an option to allow adding tasks without unlock
I often find myself picking up the phone just to write down a task, so
I've added a notification drawer quick setting to speed things up.
However, when I use this button from the lock screen, I have to unlock
my device first, which is annoying. I would like to be able to add (not
view) tasks without the need to unlock my phone.

This PR adds such an optional feature for devices running Android 8.1+.
Note that I am not an Android developer, so the implementation is
probably not perfect. However, from my testing on an emulator, this
code seems to do just what I want.
1 month ago
SC 363b29babb
Translated using Weblate (Portuguese)
Currently translated at 100.0% (655 of 655 strings)

Translation: Tasks.org/Android
Translate-URL: https://hosted.weblate.org/projects/tasks/android/pt/
2 months ago

@ -160,6 +160,10 @@ public class AndroidUtilities {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
} }
public static boolean atLeastOreoMR1() {
return Build.VERSION.SDK_INT >= VERSION_CODES.O_MR1;
}
public static boolean atLeastP() { public static boolean atLeastP() {
return VERSION.SDK_INT >= Build.VERSION_CODES.P; return VERSION.SDK_INT >= Build.VERSION_CODES.P;
} }

@ -43,6 +43,7 @@ import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
import com.google.android.material.composethemeadapter.MdcTheme import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.AndroidUtilities.atLeastOreoMR1
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
@ -150,6 +151,9 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
discardButtonClick() discardButtonClick()
} }
} }
if (atLeastOreoMR1()) {
activity?.setShowWhenLocked(preferences.showEditScreenWithoutUnlock)
}
binding = FragmentTaskEditBinding.inflate(inflater) binding = FragmentTaskEditBinding.inflate(inflater)
val view: View = binding.root val view: View = binding.root
@ -305,6 +309,13 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
return view return view
} }
override fun onDestroyView() {
super.onDestroyView()
if (atLeastOreoMR1()) {
activity?.setShowWhenLocked(false)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
taskEditEventBus taskEditEventBus
.onEach(this::process) .onEach(this::process)

@ -3,10 +3,12 @@ package org.tasks.notifications
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import com.todoroo.astrid.alarms.AlarmService
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.tasks.injection.ApplicationScope import org.tasks.injection.ApplicationScope
import org.tasks.preferences.Preferences
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -14,12 +16,23 @@ import javax.inject.Inject
class NotificationClearedReceiver : BroadcastReceiver() { class NotificationClearedReceiver : BroadcastReceiver() {
@Inject lateinit var notificationManager: NotificationManager @Inject lateinit var notificationManager: NotificationManager
@Inject @ApplicationScope lateinit var scope: CoroutineScope @Inject @ApplicationScope lateinit var scope: CoroutineScope
@Inject lateinit var preferences: Preferences
@Inject lateinit var alarmService: AlarmService
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val notificationId = intent.getLongExtra(NotificationManager.EXTRA_NOTIFICATION_ID, -1L) val notificationId = intent.getLongExtra(NotificationManager.EXTRA_NOTIFICATION_ID, -1L)
Timber.d("cleared $notificationId") Timber.d("cleared $notificationId")
if (notificationId <= 0L) return
scope.launch { scope.launch {
notificationManager.cancel(notificationId) if (preferences.useSwipeToSnooze()) {
var snoozeTime = preferences.swipeToSnoozeIntervalMS()
// snoozing for 0ms will cause the alarm service to miss this notification
// so sleep for 1s instead
if (snoozeTime == 0L) snoozeTime = 1000L
alarmService.snooze(snoozeTime, listOf(notificationId))
} else {
notificationManager.cancel(notificationId)
}
} }
} }
} }

@ -176,6 +176,9 @@ class Preferences @JvmOverloads constructor(
return if (firstDayOfWeek < 1 || firstDayOfWeek > 7) 0 else firstDayOfWeek return if (firstDayOfWeek < 1 || firstDayOfWeek > 7) 0 else firstDayOfWeek
} }
val showEditScreenWithoutUnlock: Boolean
get() = getBoolean(R.string.p_show_edit_screen_without_unlock, false)
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
fun clear() { fun clear() {
prefs.edit().clear().commit() prefs.edit().clear().commit()
@ -465,7 +468,13 @@ class Preferences @JvmOverloads constructor(
fun bundleNotifications(): Boolean = getBoolean(R.string.p_bundle_notifications, true) fun bundleNotifications(): Boolean = getBoolean(R.string.p_bundle_notifications, true)
fun usePersistentReminders(): Boolean = fun usePersistentReminders(): Boolean =
AndroidUtilities.preUpsideDownCake() && getBoolean(R.string.p_rmd_persistent, true) AndroidUtilities.preUpsideDownCake() && getBoolean(R.string.p_rmd_persistent, true)
fun useSwipeToSnooze(): Boolean =
getBoolean(R.string.p_rmd_swipe_to_snooze_enabled, false)
fun swipeToSnoozeIntervalMS(): Long =
getIntegerFromString(R.string.p_rmd_swipe_to_snooze_time_minutes, 0).toLong()
var isSyncOngoing: Boolean var isSyncOngoing: Boolean
get() = syncFlags.any { getBoolean(it, false) } get() = syncFlags.any { getBoolean(it, false) }

@ -2,6 +2,7 @@ package org.tasks.preferences.fragments
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import com.todoroo.andlib.utility.AndroidUtilities.atLeastOreoMR1
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.injection.InjectingPreferenceFragment import org.tasks.injection.InjectingPreferenceFragment
@ -21,5 +22,7 @@ class TaskEditPreferences : InjectingPreferenceFragment() {
tint = context.getColor(R.color.icon_tint_with_alpha) tint = context.getColor(R.color.icon_tint_with_alpha)
iconVisible = true iconVisible = true
} }
findPreference(R.string.p_show_edit_screen_without_unlock).isVisible = atLeastOreoMR1()
} }
} }

@ -280,7 +280,7 @@
<string name="theme_wallpaper">Fundo</string> <string name="theme_wallpaper">Fundo</string>
<string name="theme_day_night">Dia/noite</string> <string name="theme_day_night">Dia/noite</string>
<string name="language">Idioma</string> <string name="language">Idioma</string>
<string name="restart_required">O Tasks precisa ser reiniciado para que a mudança entre em vigor</string> <string name="restart_required">Reinicie o Tasks para que esta alteração tenha efeito</string>
<string name="restart_now">Reiniciar agora</string> <string name="restart_now">Reiniciar agora</string>
<string name="restart_later">Mais tarde</string> <string name="restart_later">Mais tarde</string>
<string name="settings_localization">Tradução</string> <string name="settings_localization">Tradução</string>
@ -302,9 +302,9 @@
<string name="repeats_from">Repetir de</string> <string name="repeats_from">Repetir de</string>
<string name="repeats_single">Repetir %s</string> <string name="repeats_single">Repetir %s</string>
<string name="repeats_single_on">Repetir %1$s em %2$s</string> <string name="repeats_single_on">Repetir %1$s em %2$s</string>
<string name="repeats_single_until">Repetir %1$s até %2$s</string> <string name="repeats_single_until">Repetir %1$s, termina em %2$s</string>
<string name="repeats_single_number_of_times">Repetir %1$s, ocorre %2$d %3$s</string> <string name="repeats_single_number_of_times">Repetir %1$s, ocorre %2$d %3$s</string>
<string name="repeats_single_on_until">Repetir %1$s em %2$s até %3$s</string> <string name="repeats_single_on_until">Repetir %1$s em %2$s, termina em %3$s</string>
<string name="repeats_single_on_number_of_times">Repetir %1$s em %2$s, ocorre %3$d %4$s</string> <string name="repeats_single_on_number_of_times">Repetir %1$s em %2$s, ocorre %3$d %4$s</string>
<string name="repeats_minutely">a cada minuto</string> <string name="repeats_minutely">a cada minuto</string>
<string name="repeats_hourly">de hora em hora</string> <string name="repeats_hourly">de hora em hora</string>
@ -314,13 +314,13 @@
<string name="repeats_yearly">anualmente</string> <string name="repeats_yearly">anualmente</string>
<string name="repeats_plural">Repetir a cada %s</string> <string name="repeats_plural">Repetir a cada %s</string>
<string name="repeats_plural_on">Repetir a cada %1$s em %2$s</string> <string name="repeats_plural_on">Repetir a cada %1$s em %2$s</string>
<string name="repeats_plural_until">Repetir a cada %1$s até %2$s</string> <string name="repeats_plural_until">Repetir a cada %1$s, termina em %2$s</string>
<string name="repeats_plural_number_of_times">Repetir a cada %1$s, ocorre %2$d %3$s</string> <string name="repeats_plural_number_of_times">Repetir a cada %1$s, ocorre %2$d %3$s</string>
<string name="repeats_plural_on_until">Repetir a cada %1$s em %2$s até %3$s</string> <string name="repeats_plural_on_until">Repetir a cada %1$s em %2$s, termina em %3$s</string>
<string name="repeats_plural_on_number_of_times">Repetir a cada %1$s em %2$s, ocorre %3$d %4$s</string> <string name="repeats_plural_on_number_of_times">Repetir a cada %1$s em %2$s, ocorre %3$d %4$s</string>
<string name="dont_add_to_calendar">Não adicionar ao calendário</string> <string name="dont_add_to_calendar">Não adicionar ao calendário</string>
<string name="default_calendar">Calendário predefinido</string> <string name="default_calendar">Calendário predefinido</string>
<string name="bundle_notifications_summary">Combinar várias notificações numa só notificação</string> <string name="bundle_notifications_summary">Combinar várias notificações numa só</string>
<string name="repeat_monthly_every_day_of_nth_week">cada %1$s %2$s</string> <string name="repeat_monthly_every_day_of_nth_week">cada %1$s %2$s</string>
<string name="repeat_monthly_first_week">primeiro</string> <string name="repeat_monthly_first_week">primeiro</string>
<string name="repeat_monthly_second_week">segundo</string> <string name="repeat_monthly_second_week">segundo</string>
@ -525,11 +525,11 @@
<string name="above_average">Acima da média</string> <string name="above_average">Acima da média</string>
<string name="save_percent">Guardar %d%%</string> <string name="save_percent">Guardar %d%%</string>
<string name="migrate_count">Mover %s para Tasks.org</string> <string name="migrate_count">Mover %s para Tasks.org</string>
<string name="authorization_cancelled">Autorização</string> <string name="authorization_cancelled">Autorização cancelada</string>
<string name="follow_reddit">Entrar em r/tasks</string> <string name="follow_reddit">Entrar em r/tasks</string>
<string name="current_subscription">Subscrição atual: %s</string> <string name="current_subscription">Subscrição atual: %s</string>
<string name="price_per_month">%s$/mês</string> <string name="price_per_month">$%s/mês</string>
<string name="price_per_year">%s$/ano</string> <string name="price_per_year">$%s/ano</string>
<string name="custom_filter_is_subtask">É uma subtarefa</string> <string name="custom_filter_is_subtask">É uma subtarefa</string>
<string name="backup_location_warning">AVISO: os ficheiros localizados em \"%s\" serão eliminados se o Tasks for desinstalado! Escolha outra localização para impedir que o Android elimine os seus ficheiros.</string> <string name="backup_location_warning">AVISO: os ficheiros localizados em \"%s\" serão eliminados se o Tasks for desinstalado! Escolha outra localização para impedir que o Android elimine os seus ficheiros.</string>
<string name="backups_ignore_warnings">Ignorar avisos</string> <string name="backups_ignore_warnings">Ignorar avisos</string>
@ -687,9 +687,9 @@
<string name="caldav_server_unknown">Desconhecido</string> <string name="caldav_server_unknown">Desconhecido</string>
<string name="caldav_server_other">Outro</string> <string name="caldav_server_other">Outro</string>
<string name="caldav_server_type">Tipo de servidor</string> <string name="caldav_server_type">Tipo de servidor</string>
<string name="customize_edit_screen_summary">Rearrange ou remova campos</string> <string name="customize_edit_screen_summary">Reorganizar ou remover campos</string>
<string name="hint_customize_edit_title">Demasiada informação\?</string> <string name="hint_customize_edit_title">Demasiada informação\?</string>
<string name="hint_customize_edit_body">Pode costumizar este ecrã rearranjando ou removendo campos</string> <string name="hint_customize_edit_body">Pode personalizar este ecrã reorganizando ou removendo campos</string>
<string name="filter_snoozed">Adiado</string> <string name="filter_snoozed">Adiado</string>
<string name="dismiss">Dispensar</string> <string name="dismiss">Dispensar</string>
<string name="enable_reminders">Ativar lembretes</string> <string name="enable_reminders">Ativar lembretes</string>

@ -16,6 +16,14 @@
<item>@string/none</item> <item>@string/none</item>
</string-array> </string-array>
<string-array name="swipe_to_snooze_times">
<item>@string/swipe_to_snooze_time_immediately</item>
<item>@string/swipe_to_snooze_time_15_minutes</item>
<item>@string/swipe_to_snooze_time_30_minutes</item>
<item>@string/swipe_to_snooze_time_1_hour</item>
<item>@string/swipe_to_snooze_time_24_hours</item>
</string-array>
<string-array name="reminder_ring_modes"> <string-array name="reminder_ring_modes">
<item>@string/ring_once</item> <item>@string/ring_once</item>
<item>@string/ring_five_times</item> <item>@string/ring_five_times</item>

@ -75,6 +75,17 @@
<!-- whether "clear all notifications" clears astrid notifications --> <!-- whether "clear all notifications" clears astrid notifications -->
<string name="p_rmd_persistent">notif_annoy</string> <string name="p_rmd_persistent">notif_annoy</string>
<string name="p_rmd_swipe_to_snooze_enabled">notif_swipe_to_snooze_enabled</string>
<string name="p_rmd_swipe_to_snooze_time_minutes">notif_swipe_to_snooze_time_minutes</string>
<string-array name="swipe_to_snooze_time_values">
<item>0</item>
<item>15</item>
<item>30</item>
<item>60</item>
<item>1440</item>
</string-array>
<!-- whether to vibrate phone when reminder fires --> <!-- whether to vibrate phone when reminder fires -->
<string name="p_rmd_vibrate">notif_vibrate</string> <string name="p_rmd_vibrate">notif_vibrate</string>
@ -98,6 +109,7 @@
<!-- show comments in task edit --> <!-- show comments in task edit -->
<string name="p_show_task_edit_comments">p_show_task_edit_comments</string> <string name="p_show_task_edit_comments">p_show_task_edit_comments</string>
<string name="p_show_edit_screen_without_unlock">show_edit_screen_without_unlock</string>
<string-array name="EPr_reminder_random_hours"> <string-array name="EPr_reminder_random_hours">
<!-- values (in hours) associated with random reminders above. --> <!-- values (in hours) associated with random reminders above. -->

@ -150,6 +150,14 @@ File %1$s contained %2$s.\n\n
<string name="rmd_EPr_rmd_time_desc">Notifications for tasks without due times will appear at %s</string> <string name="rmd_EPr_rmd_time_desc">Notifications for tasks without due times will appear at %s</string>
<string name="persistent_notifications">Persistent notifications</string> <string name="persistent_notifications">Persistent notifications</string>
<string name="persistent_notifications_description">Persistent notifications cannot be cleared</string> <string name="persistent_notifications_description">Persistent notifications cannot be cleared</string>
<string name="swipe_to_snooze_title">Swipe to snooze</string>
<string name="swipe_to_snooze_description">Snooze time</string>
<string name="swipe_to_snooze_time_description">A cleared notification will be snoozed and recreated %s</string>
<string name="swipe_to_snooze_time_immediately">immediately</string>
<string name="swipe_to_snooze_time_15_minutes">after 15 minutes</string>
<string name="swipe_to_snooze_time_30_minutes">after 30 minutes</string>
<string name="swipe_to_snooze_time_1_hour">after 1 hour</string>
<string name="swipe_to_snooze_time_24_hours">after 24 hours</string>
<string name="rmd_EPr_defaultRemind_title">Random reminders</string> <string name="rmd_EPr_defaultRemind_title">Random reminders</string>
<string name="default_random_reminder_disabled">Disabled</string> <string name="default_random_reminder_disabled">Disabled</string>
<string name="default_random_reminder_hourly">Hourly</string> <string name="default_random_reminder_hourly">Hourly</string>
@ -369,6 +377,8 @@ File %1$s contained %2$s.\n\n
<string name="url_invalid_scheme">Must begin with http(s)://</string> <string name="url_invalid_scheme">Must begin with http(s)://</string>
<string name="no_title">(No title)</string> <string name="no_title">(No title)</string>
<string name="back_button_saves_task">Back button saves task</string> <string name="back_button_saves_task">Back button saves task</string>
<string name="show_edit_screen_without_unlock">Show edit screen without unlock</string>
<string name="show_edit_screen_without_unlock_summary">Enables use of Quick Settings tile without unlocking device</string>
<string name="default_list">Default list</string> <string name="default_list">Default list</string>
<string name="default_tags">Default tags</string> <string name="default_tags">Default tags</string>
<string name="default_recurrence">Default recurrence</string> <string name="default_recurrence">Default recurrence</string>

@ -71,6 +71,23 @@
android:summary="@string/more_notification_settings_summary" android:summary="@string/more_notification_settings_summary"
app:icon="@drawable/ic_open_in_new_24px" /> app:icon="@drawable/ic_open_in_new_24px" />
<PreferenceCategory android:title="@string/swipe_to_snooze_title">
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="@string/p_rmd_swipe_to_snooze_enabled"
android:title="@string/enabled" />
<ListPreference
android:defaultValue="15"
android:entries="@array/swipe_to_snooze_times"
android:entryValues="@array/swipe_to_snooze_time_values"
android:key="@string/p_rmd_swipe_to_snooze_time_minutes"
android:summary="@string/swipe_to_snooze_time_description"
android:title="@string/swipe_to_snooze_description"
android:dependency="@string/p_rmd_swipe_to_snooze_enabled" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/default_reminder"> <PreferenceCategory android:title="@string/default_reminder">
<SwitchPreferenceCompat <SwitchPreferenceCompat

@ -35,4 +35,11 @@
android:title="@string/EPr_show_task_edit_comments" android:title="@string/EPr_show_task_edit_comments"
app:singleLineTitle="false" /> app:singleLineTitle="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="@string/p_show_edit_screen_without_unlock"
android:title="@string/show_edit_screen_without_unlock"
android:summary="@string/show_edit_screen_without_unlock_summary"
app:singleLineTitle="false" />
</PreferenceScreen> </PreferenceScreen>

Loading…
Cancel
Save