Material date time pickers everywhere

Also remove calendar and clock style preferences. App will keep track of
what type of input you use when you switch
first_day_of_week
Alex Baker 9 months ago
parent 70ff2ad79f
commit eb9dd40103

@ -27,7 +27,6 @@ import org.tasks.data.entity.Alarm
import org.tasks.data.entity.Alarm.Companion.TYPE_DATE_TIME
import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.MyTimePickerDialog
import org.tasks.extensions.Context.openReminderSettings
import org.tasks.scheduling.NotificationSchedulerIntentService
import org.tasks.ui.TaskEditControlFragment
@ -75,7 +74,7 @@ class ReminderControlSet : TaskEditControlFragment() {
if (result.resultCode != RESULT_OK) return@rememberLauncherForActivityResult
val data = result.data ?: return@rememberLauncherForActivityResult
val timestamp =
data.getLongExtra(MyTimePickerDialog.EXTRA_TIMESTAMP, 0L)
data.getLongExtra(DateAndTimePickerActivity.EXTRA_TIMESTAMP, 0L)
val replace: Alarm? = data.getParcelableExtra(EXTRA_REPLACE)
replace?.let { viewModel.removeAlarm(it) }
viewModel.addAlarm(Alarm(time = timestamp, type = TYPE_DATE_TIME))

@ -2,16 +2,22 @@ package org.tasks.activities
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.timepicker.MaterialTimePicker
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.dialogs.MyDatePickerDialog.Companion.dateInputMode
import org.tasks.dialogs.MyDatePickerDialog.Companion.newDatePicker
import org.tasks.dialogs.MyTimePickerDialog
import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker
import org.tasks.dialogs.MyTimePickerDialog.Companion.timeInputMode
import org.tasks.compose.pickers.DatePickerDialog
import org.tasks.compose.pickers.TimePickerDialog
import org.tasks.extensions.Context.is24HourFormat
import org.tasks.preferences.Preferences
import org.tasks.themes.TasksTheme
import org.tasks.themes.Theme
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils2.currentTimeMillis
import javax.inject.Inject
@ -19,89 +25,64 @@ import javax.inject.Inject
@AndroidEntryPoint
class DateAndTimePickerActivity : AppCompatActivity() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var theme: Theme
private var initial: DateTime? = null
private var dateSelected: DateTime? = null
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initial = DateTime(intent.getLongExtra(EXTRA_TIMESTAMP, currentTimeMillis()))
dateSelected =
savedInstanceState
?.getLong(EXTRA_DATE_SELECTED)
?.takeIf { it > 0 }
?.let { DateTime(it, DateTime.UTC) }
if (dateSelected != null) {
showTimePicker()
} else {
showDatePicker(initial ?: DateTime())
}
}
private fun showDatePicker(date: DateTime) {
dateSelected = null
val picker =
supportFragmentManager
.findFragmentByTag(FRAG_TAG_DATE_PICKER) as? MaterialDatePicker<Long>
?: newDatePicker(date.millis, preferences.dateInputMode).apply {
show(supportFragmentManager, FRAG_TAG_DATE_PICKER)
setContent {
TasksTheme(
theme = theme.themeBase.index,
primary = theme.themeColor.primaryColor,
) {
var dateSelected by rememberSaveable {
mutableLongStateOf(intent.getLongExtra(EXTRA_TIMESTAMP, currentTimeMillis()))
}
var showTimePicker by rememberSaveable { mutableStateOf(false) }
if (showTimePicker) {
TimePickerDialog(
millisOfDay = 0,
is24Hour = is24HourFormat,
initialDisplayMode = remember { preferences.timeDisplayMode },
setDisplayMode = { preferences.timeDisplayMode = it },
selected = {
val data = Intent()
data.putExtras(intent)
data.putExtra(
EXTRA_TIMESTAMP,
DateTime(dateSelected).withMillisOfDay(it).millis
)
setResult(RESULT_OK, data)
finish()
},
dismiss = { showTimePicker = false },
)
} else {
DatePickerDialog(
initialDate = remember {
intent.getLongExtra(
EXTRA_TIMESTAMP,
currentTimeMillis()
)
},
displayMode = remember { preferences.calendarDisplayMode },
setDisplayMode = {
preferences.calendarDisplayMode = it
},
selected = {
dateSelected = it
showTimePicker = true
},
dismiss = {
finish()
},
)
}
picker.apply {
addOnPositiveButtonClickListener {
dateSelected = DateTime(selection!!, DateTime.UTC)
showTimePicker()
}
addOnCancelListener { finish() }
addOnNegativeButtonClickListener { finish() }
}
}
private fun showTimePicker() {
val fragmentManager = supportFragmentManager
val picker =
fragmentManager
.findFragmentByTag(FRAG_TAG_TIME_PICKER) as? MaterialTimePicker
?: newTimePicker(
this,
DateTime(dateSelected!!.year, dateSelected!!.monthOfYear, dateSelected!!.dayOfMonth)
.withMillisOfDay(initial!!.millisOfDay).millis,
preferences.timeInputMode
).apply { show(fragmentManager, FRAG_TAG_TIME_PICKER) }
picker.apply {
addOnCancelListener {
dateSelected?.let { showDatePicker(it) } ?: finish()
}
addOnNegativeButtonClickListener {
dateSelected?.let { showDatePicker(it) } ?: finish()
}
addOnPositiveButtonClickListener {
val data = Intent()
data.putExtras(intent)
data.putExtra(
MyTimePickerDialog.EXTRA_TIMESTAMP,
DateTime(
dateSelected!!.year,
dateSelected!!.monthOfYear,
dateSelected!!.dayOfMonth,
hour,
minute
).millis
)
setResult(RESULT_OK, data)
finish()
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
dateSelected?.let { outState.putLong(EXTRA_DATE_SELECTED, it.millis) }
}
companion object {
const val EXTRA_TIMESTAMP = "extra_timestamp"
private const val FRAG_TAG_DATE_PICKER = "frag_tag_date_picker"
private const val FRAG_TAG_TIME_PICKER = "frag_tag_time_picker"
private const val EXTRA_DATE_SELECTED = "extra_date_selected"
}
}

@ -22,6 +22,7 @@ import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@ -76,6 +77,8 @@ fun CustomRecurrence(
setOccurrences: (Int) -> Unit,
toggleDay: (DayOfWeek) -> Unit,
setMonthSelection: (Int) -> Unit,
calendarDisplayMode: DisplayMode,
setDisplayMode: (DisplayMode) -> Unit,
) {
BackHandler {
save()
@ -185,6 +188,8 @@ fun CustomRecurrence(
setEndDate = setEndDate,
setSelection = setSelectedEndType,
setOccurrences = setOccurrences,
calendarDisplayMode = calendarDisplayMode,
setDisplayMode = setDisplayMode,
)
}
}
@ -319,11 +324,14 @@ private fun MonthlyPicker(
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun EndsPicker(
selection: Int,
endDate: Long,
endOccurrences: Int,
calendarDisplayMode: DisplayMode,
setDisplayMode: (DisplayMode) -> Unit,
setOccurrences: (Int) -> Unit,
setEndDate: (Long) -> Unit,
setSelection: (Int) -> Unit,
@ -352,7 +360,12 @@ private fun EndsPicker(
if (showDatePicker) {
DatePickerDialog(
initialDate = endDate,
selected = { setEndDate(it) },
displayMode = calendarDisplayMode,
setDisplayMode = setDisplayMode,
selected = {
setEndDate(it)
showDatePicker = false
},
dismiss = { showDatePicker = false },
)
}
@ -414,6 +427,7 @@ private val Recur.Frequency.plural: Int
else -> throw RuntimeException()
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -430,10 +444,13 @@ fun WeeklyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -450,10 +467,13 @@ fun MonthlyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -470,10 +490,13 @@ fun MinutelyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -490,10 +513,13 @@ fun HourlyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -510,10 +536,13 @@ fun DailyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -530,6 +559,8 @@ fun YearlyPreview() {
setOccurrences = {},
toggleDay = {},
setMonthSelection = {},
calendarDisplayMode = DisplayMode.Picker,
setDisplayMode = {},
)
}
}

@ -13,10 +13,16 @@ import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.CalendarMonth
import androidx.compose.material.icons.outlined.Keyboard
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDefaults
import androidx.compose.material3.DatePickerState
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Surface
@ -36,6 +42,7 @@ fun DatePickerBottomSheet(
showButtons: Boolean,
dismiss: () -> Unit,
accept: () -> Unit,
setDisplayMode: (DisplayMode) -> Unit,
dateShortcuts: @Composable ColumnScope.() -> Unit,
timeShortcuts: @Composable ColumnScope.() -> Unit,
state: DatePickerState,
@ -88,6 +95,26 @@ fun DatePickerBottomSheet(
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(
onClick = {
state.displayMode = if (state.displayMode == DisplayMode.Input) {
DisplayMode.Picker
} else {
DisplayMode.Input
}
setDisplayMode(state.displayMode)
},
) {
Icon(
imageVector = if (state.displayMode == DisplayMode.Input) {
Icons.Outlined.CalendarMonth
} else {
Icons.Outlined.Keyboard
},
contentDescription = null
)
}
Spacer(modifier = Modifier.weight(1f))
TextButton(
onClick = { dismiss() }
) {

@ -2,11 +2,13 @@ package org.tasks.compose.pickers
import android.content.res.Configuration
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
@ -15,11 +17,14 @@ import androidx.compose.ui.tooling.preview.Preview
import org.tasks.R
import org.tasks.themes.TasksTheme
import org.tasks.time.DateTime
import timber.log.Timber
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DatePickerDialog(
initialDate: Long,
displayMode: DisplayMode,
setDisplayMode: (DisplayMode) -> Unit,
selected: (Long) -> Unit,
dismiss: () -> Unit,
) {
@ -34,31 +39,36 @@ fun DatePickerDialog(
}
val datePickerState = rememberDatePickerState(
initialSelectedDateMillis = initialDateUTC,
initialDisplayMode = displayMode,
)
LaunchedEffect(datePickerState.displayMode) {
Timber.d("Set display mode to ${datePickerState.displayMode}")
setDisplayMode(datePickerState.displayMode)
}
androidx.compose.material3.DatePickerDialog(
onDismissRequest = { dismiss() },
dismissButton = {
TextButton(onClick = dismiss) {
Text(text = stringResource(id = R.string.cancel))
}
TextButton(onClick = dismiss) {
Text(text = stringResource(id = R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
datePickerState
.selectedDateMillis
?.let { selected(it - DateTime(it).offset) }
dismiss()
TextButton(
onClick = {
datePickerState
.selectedDateMillis
?.let { selected(it - DateTime(it).offset) }
}
) {
Text(text = stringResource(id = R.string.ok))
}
) {
Text(text = stringResource(id = R.string.ok))
}
}
) {
DatePicker(state = datePickerState)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -66,8 +76,26 @@ fun DatePickerPreview() {
TasksTheme {
DatePickerDialog(
initialDate = DateTime().plusDays(1).millis,
displayMode = DisplayMode.Picker,
setDisplayMode = {},
selected = {},
dismiss = {}
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun DatePickerPreviewInput() {
TasksTheme {
DatePickerDialog(
initialDate = DateTime().plusDays(1).millis,
displayMode = DisplayMode.Input,
setDisplayMode = {},
selected = {},
dismiss = {}
)
}
}

@ -12,6 +12,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Keyboard
import androidx.compose.material.icons.outlined.Schedule
import androidx.compose.material3.BasicAlertDialog
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@ -42,7 +43,8 @@ import org.tasks.R
fun TimePickerDialog(
millisOfDay: Int,
is24Hour: Boolean,
textInput: Boolean,
initialDisplayMode: DisplayMode,
setDisplayMode: (DisplayMode) -> Unit,
selected: (Int) -> Unit,
dismiss: () -> Unit,
) {
@ -51,7 +53,7 @@ fun TimePickerDialog(
initialMinute = (millisOfDay / (60_000)) % 60,
is24Hour = is24Hour
)
var showingTextInput by remember { mutableStateOf(textInput) }
var displayMode by remember { mutableStateOf(initialDisplayMode) }
val layoutType = with(LocalConfiguration.current) {
if (screenHeightDp < screenWidthDp) {
TimePickerLayoutType.Horizontal
@ -80,7 +82,7 @@ fun TimePickerDialog(
.weight(1f, fill = false),
contentAlignment = Alignment.Center,
) {
if (showingTextInput) {
if (displayMode == DisplayMode.Input) {
TimeInput(
state = state,
colors = TimePickerDefaults.colors(
@ -108,10 +110,17 @@ fun TimePickerDialog(
verticalAlignment = Alignment.CenterVertically,
) {
IconButton(
onClick = { showingTextInput = !showingTextInput },
onClick = {
displayMode = if (displayMode == DisplayMode.Input) {
DisplayMode.Picker
} else {
DisplayMode.Input
}
setDisplayMode(displayMode)
},
) {
Icon(
imageVector = if (showingTextInput) {
imageVector = if (displayMode == DisplayMode.Input) {
Icons.Outlined.Schedule
} else {
Icons.Outlined.Keyboard

@ -31,7 +31,6 @@ import org.tasks.data.createDueDate
import org.tasks.data.entity.Task
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.dialogs.MyTimePickerDialog.Companion.timeInputMode
import org.tasks.extensions.Context.is24HourFormat
import org.tasks.notifications.NotificationManager
import org.tasks.themes.TasksTheme
@ -117,10 +116,13 @@ class DateTimePicker : BaseDateTimePicker() {
savedInstanceState: Bundle?,
) = content {
TasksTheme(theme = theme.themeBase.index) {
val state = rememberDatePickerState()
val state = rememberDatePickerState(
initialDisplayMode = remember { preferences.calendarDisplayMode },
)
DatePickerBottomSheet(
state = state,
showButtons = !autoclose,
setDisplayMode = { preferences.calendarDisplayMode = it },
dismiss = { onDismissHandler?.onDismiss() ?: dismiss() },
accept = { sendSelected() },
dateShortcuts = {
@ -160,7 +162,8 @@ class DateTimePicker : BaseDateTimePicker() {
TimePickerDialog(
millisOfDay = time,
is24Hour = remember { requireContext().is24HourFormat },
textInput = remember { preferences.timeInputMode == 1 },
initialDisplayMode = remember { preferences.timeDisplayMode },
setDisplayMode = { preferences.timeDisplayMode = it },
selected = { returnSelectedTime(it + 1000) },
dismiss = { showTimePicker = false },
)

@ -1,81 +0,0 @@
package org.tasks.dialogs
import android.app.Activity.RESULT_CANCELED
import android.app.Activity.RESULT_OK
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.datepicker.MaterialDatePicker.INPUT_MODE_CALENDAR
import com.google.android.material.datepicker.MaterialDatePicker.INPUT_MODE_TEXT
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils2.currentTimeMillis
import org.tasks.time.startOfDay
import javax.inject.Inject
@AndroidEntryPoint
class MyDatePickerDialog : DialogFragment() {
@Inject lateinit var preferences: Preferences
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val fragment =
(childFragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) as? MaterialDatePicker<Long>)
?: newDatePicker(initial, preferences.dateInputMode)
.let {
childFragmentManager
.beginTransaction()
.add(it, FRAG_TAG_DATE_PICKER)
.commit()
it
}
with(fragment) {
addOnPositiveButtonClickListener {
val dt = DateTime(it, DateTime.UTC)
selected(dt.year, dt.monthOfYear, dt.dayOfMonth)
}
addOnCancelListener { cancel() }
addOnNegativeButtonClickListener { cancel() }
}
}
private val initial: Long
get() = arguments?.getLong(MyTimePickerDialog.EXTRA_TIMESTAMP) ?: currentTimeMillis().startOfDay()
private fun selected(year: Int, month: Int, day: Int) {
targetFragment?.onActivityResult(
targetRequestCode,
RESULT_OK,
Intent().putExtra(EXTRA_TIMESTAMP, DateTime(year, month, day).millis)
)
dismiss()
}
private fun cancel() {
targetFragment?.onActivityResult(targetRequestCode, RESULT_CANCELED, null)
dismiss()
}
companion object {
const val FRAG_TAG_DATE_PICKER = "frag_date_picker"
const val EXTRA_TIMESTAMP = "extra_timestamp"
@JvmStatic
fun newDatePicker(initial: Long, inputMode: Int) =
MaterialDatePicker.Builder.datePicker()
// TODO: figure out hack for first day of week
.setInputMode(inputMode)
.setSelection(if (initial > 0) initial else currentTimeMillis())
.build()
val Preferences.dateInputMode: Int
get() = when (getIntegerFromString(R.string.p_picker_mode_date, 0)) {
1 -> INPUT_MODE_TEXT
else -> INPUT_MODE_CALENDAR
}
}
}

@ -1,78 +1,65 @@
package org.tasks.dialogs
import android.app.Activity
import android.app.Activity.RESULT_CANCELED
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.format.DateFormat.is24HourFormat
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.remember
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.MaterialTimePicker.INPUT_MODE_CLOCK
import com.google.android.material.timepicker.MaterialTimePicker.INPUT_MODE_KEYBOARD
import com.google.android.material.timepicker.TimeFormat.CLOCK_12H
import com.google.android.material.timepicker.TimeFormat.CLOCK_24H
import androidx.fragment.compose.content
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.compose.pickers.TimePickerDialog
import org.tasks.extensions.Context.is24HourFormat
import org.tasks.preferences.Preferences
import org.tasks.time.DateTime
import org.tasks.themes.TasksTheme
import org.tasks.themes.Theme
import org.tasks.time.DateTimeUtils2.currentTimeMillis
import org.tasks.time.millisOfDay
import org.tasks.time.startOfDay
import org.tasks.time.withMillisOfDay
import javax.inject.Inject
@AndroidEntryPoint
class MyTimePickerDialog : DialogFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var theme: Theme
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val fragment =
(childFragmentManager.findFragmentByTag(FRAG_TAG_TIME_PICKER) as? MaterialTimePicker)
?: newTimePicker(requireContext(), initial, preferences.timeInputMode)
.let {
childFragmentManager
.beginTransaction()
.add(it, FRAG_TAG_TIME_PICKER)
.commit()
it
}
with(fragment) {
addOnPositiveButtonClickListener { selected(hour, minute) }
addOnNegativeButtonClickListener { cancel() }
addOnCancelListener { cancel() }
@OptIn(ExperimentalMaterial3Api::class)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?,
) = content {
TasksTheme(
theme = theme.themeBase.index,
primary = theme.themeColor.primaryColor,
) {
TimePickerDialog(
millisOfDay = remember { initial.millisOfDay },
is24Hour = remember { requireContext().is24HourFormat },
initialDisplayMode = remember { preferences.timeDisplayMode },
setDisplayMode = { preferences.timeDisplayMode = it },
selected = {
targetFragment?.onActivityResult(
targetRequestCode,
Activity.RESULT_OK,
Intent().putExtra(EXTRA_TIMESTAMP, initial.withMillisOfDay(it))
)
dismiss()
},
dismiss = { dismiss() },
)
}
}
private val initial: Long
get() = arguments?.getLong(EXTRA_TIMESTAMP) ?: currentTimeMillis().startOfDay()
private fun selected(hour: Int, minute: Int) {
targetFragment?.onActivityResult(
targetRequestCode,
Activity.RESULT_OK,
Intent().putExtra(
EXTRA_TIMESTAMP,
initial
.toDateTime()
.startOfDay()
.withHourOfDay(hour)
.withMinuteOfHour(minute)
.millis
)
)
dismiss()
}
private fun cancel() {
targetFragment?.onActivityResult(targetRequestCode, RESULT_CANCELED, null)
dismiss()
}
companion object {
const val FRAG_TAG_TIME_PICKER = "frag_time_picker"
const val EXTRA_TIMESTAMP = "extra_timestamp"
fun newTimePicker(
@ -86,22 +73,5 @@ class MyTimePickerDialog : DialogFragment() {
}
setTargetFragment(target, rc)
}
@JvmStatic
fun newTimePicker(context: Context?, initial: Long, inputMode: Int) =
DateTime(initial).let {
MaterialTimePicker.Builder()
.setInputMode(inputMode)
.setTimeFormat(if (is24HourFormat(context)) CLOCK_24H else CLOCK_12H)
.setHour(it.hourOfDay)
.setMinute(it.minuteOfHour)
.build()
}
val Preferences.timeInputMode: Int
get() = when (getIntegerFromString(R.string.p_picker_mode_time, 0)) {
1 -> INPUT_MODE_KEYBOARD
else -> INPUT_MODE_CLOCK
}
}
}
}

@ -26,7 +26,6 @@ import org.tasks.compose.pickers.TimePickerDialog
import org.tasks.compose.pickers.TimeShortcuts
import org.tasks.data.entity.Task
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.MyTimePickerDialog.Companion.timeInputMode
import org.tasks.extensions.Context.is24HourFormat
import org.tasks.notifications.NotificationManager
import org.tasks.themes.TasksTheme
@ -84,10 +83,13 @@ class StartDatePicker : BaseDateTimePicker() {
savedInstanceState: Bundle?
) = content {
TasksTheme(theme = theme.themeBase.index) {
val state = rememberDatePickerState()
val state = rememberDatePickerState(
initialDisplayMode = remember { preferences.calendarDisplayMode },
)
DatePickerBottomSheet(
state = state,
showButtons = !autoclose,
setDisplayMode = { preferences.calendarDisplayMode = it },
dismiss = { onDismissHandler?.onDismiss() ?: dismiss() },
accept = { sendSelected() },
dateShortcuts = {
@ -112,7 +114,8 @@ class StartDatePicker : BaseDateTimePicker() {
TimePickerDialog(
millisOfDay = time,
is24Hour = remember { requireContext().is24HourFormat },
textInput = remember { preferences.timeInputMode == 1 },
initialDisplayMode = remember { preferences.timeDisplayMode },
setDisplayMode = { preferences.timeDisplayMode = it },
selected = { returnSelectedTime(it + 1000) },
dismiss = { showTimePicker = false }
)

@ -9,6 +9,8 @@ import android.content.pm.PackageManager
import android.media.RingtoneManager
import android.net.Uri
import android.os.Binder
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.core.app.NotificationCompat
import androidx.core.net.toUri
import androidx.documentfile.provider.DocumentFile
@ -588,6 +590,22 @@ class Preferences @JvmOverloads constructor(
val multilineTitle: Boolean
get() = getBoolean(R.string.p_multiline_title, false)
@OptIn(ExperimentalMaterial3Api::class)
var calendarDisplayMode: DisplayMode
get() = if (getIntegerFromString(R.string.p_picker_mode_date, 0) == 1)
DisplayMode.Input else DisplayMode.Picker
set(mode) {
setStringFromInteger(R.string.p_picker_mode_date, if (mode == DisplayMode.Input) 1 else 0)
}
@OptIn(ExperimentalMaterial3Api::class)
var timeDisplayMode: DisplayMode
get() = if (getIntegerFromString(R.string.p_picker_mode_time, 0) == 1)
DisplayMode.Input else DisplayMode.Picker
set(mode) {
setStringFromInteger(R.string.p_picker_mode_time, if (mode == DisplayMode.Input) 1 else 0)
}
companion object {
private fun getSharedPreferencesName(context: Context): String =
context.packageName + "_preferences"

@ -13,7 +13,6 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import org.tasks.activities.DateAndTimePickerActivity
import org.tasks.dialogs.MyTimePickerDialog
import org.tasks.time.DateTime
import javax.inject.Inject
@ -81,7 +80,7 @@ class SnoozeActivity : AppCompatActivity(), SnoozeCallback, DialogInterface.OnCa
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_DATE_TIME) {
if (resultCode == Activity.RESULT_OK && data != null) {
val timestamp = data.getLongExtra(MyTimePickerDialog.EXTRA_TIMESTAMP, 0L)
val timestamp = data.getLongExtra(DateAndTimePickerActivity.EXTRA_TIMESTAMP, 0L)
snoozeForTime(DateTime(timestamp))
} else {
finish()

@ -5,10 +5,13 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.remember
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.compose.pickers.CustomRecurrence
import org.tasks.preferences.Preferences
import org.tasks.themes.TasksTheme
import org.tasks.themes.Theme
import javax.inject.Inject
@ -16,9 +19,11 @@ import javax.inject.Inject
@AndroidEntryPoint
class CustomRecurrenceActivity : FragmentActivity() {
@Inject lateinit var theme: Theme
@Inject lateinit var preferences: Preferences
val viewModel: CustomRecurrenceViewModel by viewModels()
@OptIn(ExperimentalMaterial3Api::class)
override fun onPostCreate(savedInstanceState: Bundle?) {
super.onPostCreate(savedInstanceState)
setContent {
@ -37,6 +42,8 @@ class CustomRecurrenceActivity : FragmentActivity() {
setOccurrences = { viewModel.setOccurrences(it) },
toggleDay = { viewModel.toggleDay(it) },
setMonthSelection = { viewModel.setMonthSelection(it) },
calendarDisplayMode = remember { preferences.calendarDisplayMode },
setDisplayMode = { preferences.calendarDisplayMode = it }
)
}
}

@ -282,8 +282,6 @@
<string name="FLA_new_filter">أنشأ تصفيةً جديدة</string>
<string name="sort_created">بتاريخ الإنشاء</string>
<string name="sort_start_group">تبدأ %s</string>
<string name="picker_mode_clock">الساعة</string>
<string name="picker_mode_calendar">التقويم</string>
<string name="invite">أرسل دعوة</string>
<string name="email">البريد اﻹلكتروني</string>
<string name="app_password_enter_description">أعط كلمة سرّك اسمًا (اختياري)</string>
@ -477,9 +475,6 @@
<string name="upgrade_more_customization_description">افتح جميع الثيمات والألوان والرموز</string>
<string name="upgrade_more_customization">المزيد من التخصيص</string>
<string name="pro_free_trial">يحصل المشتركون الجدد على نسخة تجريبية مجانية مدتها 7 أيام. تلغى في أي وقت</string>
<string name="picker_mode_text">نص</string>
<string name="picker_mode_time">وضع منتقي الوقت</string>
<string name="picker_mode_date">وضع منتقي التاريخ</string>
<string name="remove_user_confirmation">%1$s لا يملك حق الوصول ل%2$s</string>
<string name="account_not_included">غير مشمول في اشتراكات \"ضع سعرك\"</string>
<string name="app_password_save">استخدم بيانات الاعتماد هذه لتكوين تطبيق تابع لجهة خارجية. يمنحون حق الوصول الكامل إلى حساب Tasks.org الخاص بك ، ولا تكتبها بالاسفل أو تشاركها مع أي شخص!</string>

@ -426,10 +426,7 @@
<string name="astrid_sort_order_summary">Използвайте режима за ръчно сортиране на Astrid за „Моите задачи“, „Днес“ и етикетите. Този режим на сортиране ще бъде заменен с „Моя подредба“ в бъдещо издание</string>
<string name="astrid_sort_order">Ръчно сортиране на Astrid</string>
<string name="SSD_sort_my_order">Моя подредба</string>
<string name="picker_mode_clock">Часовник</string>
<string name="invite">Покана</string>
<string name="picker_mode_calendar">Календар</string>
<string name="picker_mode_text">Текст</string>
<string name="markdown">Markdown</string>
<string name="license_summary">Tasks е софтуер с отворен код, лицензиран под GNU General Public License v3.0</string>
<string name="this_feature_requires_a_subscription">Тази възможност изисква абонамент</string>
@ -546,7 +543,6 @@
<string name="randomly_every">Произволно на всеки %s</string>
<string name="multi_select_reschedule">Пренасрочване</string>
<string name="auto_dismiss_datetime">Автоматично затваряне след избор на дата и час</string>
<string name="picker_mode_time">Режим на избор на час</string>
<string name="more_options">Допълнителни настройки</string>
<string name="auto_dismiss_datetime_list_summary">Затваряне след избор от списъка със задачи</string>
<string name="shortcut_pick_time">Час по избор</string>
@ -589,7 +585,6 @@
<string name="invite_declined">Поканата е отхвърлена</string>
<string name="invite_awaiting_response">Поканата очаква орговор</string>
<string name="invite_invalid">Поканата е недейсвителна</string>
<string name="picker_mode_date">Режим избор на дата</string>
<string name="app_passwords">Пароли на приложениятя</string>
<string name="current_subscription">Текущ абонамент: %s</string>
<string name="price_per_year">$%s/година</string>

@ -620,11 +620,6 @@
<string name="upgrade_more_customization_description">Odemknout všechny vzhledy, barvy a ikony</string>
<string name="upgrade_more_customization">Další přizpůsobení</string>
<string name="pro_free_trial">Noví předplatitelé dostanou 7 dnů na vyzkoušení zdarma. Předplatné je možné kdykoli zrušit</string>
<string name="picker_mode_text">Text</string>
<string name="picker_mode_clock">Hodiny</string>
<string name="picker_mode_calendar">Kalendář</string>
<string name="picker_mode_time">Režim výběru času</string>
<string name="picker_mode_date">Režim výběru data</string>
<string name="invite_invalid">Neplatné pozvání</string>
<string name="invite_awaiting_response">Pozvání čeká na odpověď</string>
<string name="invite_declined">Pozvání odmítnuto</string>

@ -561,11 +561,6 @@
<string name="upgrade_more_customization_description">Låse alle temaer, farver og ikoner op</string>
<string name="upgrade_more_customization">Mere tilpasning</string>
<string name="pro_free_trial">Nye abonnenter får en gratis prøveperiode på 7 dage. Du kan til enhver tid annullere</string>
<string name="picker_mode_text">Tekst</string>
<string name="picker_mode_clock">Ur</string>
<string name="picker_mode_calendar">kalender</string>
<string name="picker_mode_time">Time picker-tilstand</string>
<string name="picker_mode_date">Tilstand for datovælger</string>
<string name="invite_invalid">Invitere ugyldig</string>
<string name="invite_awaiting_response">Invitation afventer svar</string>
<string name="invite_declined">Invitation afvist</string>

@ -604,11 +604,6 @@
<string name="upgrade_more_customization_description">Schalte alle Themen, Farben und Symbole frei</string>
<string name="upgrade_more_customization">Mehr Anpassungsmöglichkeiten</string>
<string name="pro_free_trial">Neue Abonnenten erhalten eine 7-tägige kostenlose Testversion. Jederzeit abbrechen</string>
<string name="picker_mode_text">Text</string>
<string name="picker_mode_clock">Uhr</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="picker_mode_time">Zeitauswahlmodus</string>
<string name="picker_mode_date">Datumsauswahlmodus</string>
<string name="next_saturday">Nächsten Samstag</string>
<string name="next_friday">Nächsten Freitag</string>
<string name="next_thursday">Nächsten Donnerstag</string>

@ -366,7 +366,6 @@
<string name="gtasks_GLA_errorIOAuth">Bedaŭrinde ni spertis problemon dum komuniki kun serviloj de Google. Bonvolu repeni poste.</string>
<string name="persistent_notifications_description">Daŭraj sciigoj ne povas esti forigitaj</string>
<string name="action_new_task">Nova tasko</string>
<string name="picker_mode_text">Teksto</string>
<string name="alarm_after_start">%s post komenco</string>
<string name="astrid_sort_order_summary">Por ebligi manan ordigon de Astrid por \'Miaj Taskoj\', \'Hodiaŭ\', kaj etikedoj. Ĉi tiu maniero de ordigi estos anstataŭigita per \'Mia ordigo\' per estonta ĝisdatigo</string>
<string name="EPr_default_location_reminder_title">Defaŭltaj lokaj memorigiloj</string>
@ -415,7 +414,6 @@
<string name="sign_in_with_google">Ensaluti per Google</string>
<string name="sign_in_with_github">Ensaluti per GitHub</string>
<string name="invite_invalid">Nevalida invito</string>
<string name="picker_mode_clock">Horloĝo</string>
<string name="consent_agree">Konsenti</string>
<string name="consent_deny">Ne nun</string>
<string name="sort_sorting">Ordigo</string>
@ -539,7 +537,6 @@
<string name="tasks_org_account">Tasks.org konto</string>
<string name="remove_user">Forigi uzanton?</string>
<string name="invite_awaiting_response">Invito atendas respondon</string>
<string name="picker_mode_calendar">Kalendaro</string>
<string name="pro_free_trial">Novaj abonantoj ricevas provperiodon de 7 tagoj. Iam ajn nuligi ĝin</string>
<string name="upgrade_more_customization">Pli da adapto</string>
<string name="caldav_server_unknown">Nekonata</string>
@ -675,8 +672,6 @@
<string name="your_subscription_expired">Via abono finiĝis. Abonu tuj por reaktivigi servon.</string>
<string name="upgrade_tasks_org_account_description">Sinkronigi kun Tasks.org kaj kunlabori kun aliaj uzantoj</string>
<string name="app_password_save">Uzu ĉi tiujn identigilojn por agordi aplikaĵon de ekstera liveranto. Ili permesas tutan atingorajton al via Tasks.org konto. Ne skribi ilin aŭ konigi ilin al iu ajn!</string>
<string name="picker_mode_date">Datelektila reĝimo</string>
<string name="picker_mode_time">Tempelektila reĝimo</string>
<string name="upgrade_more_customization_description">Malŝlosi ĉiujn etosojn, kolorojn, kaj piktogramojn</string>
<string name="upgrade_desktop_access">Aliri per labortablo</string>
<string name="account_not_included">Ne inkluzivite per \'Elekti propran prezon\' abonoj</string>

@ -617,11 +617,6 @@
<string name="invite">Invitar</string>
<string name="email">Correo electrónico</string>
<string name="share_list">Compartir lista</string>
<string name="picker_mode_text">Texto</string>
<string name="picker_mode_clock">Reloj</string>
<string name="picker_mode_calendar">Calendario</string>
<string name="picker_mode_time">Modo de selección del tiempo</string>
<string name="picker_mode_date">Modo de selección de fecha</string>
<string name="more_options">Más opciones</string>
<string name="upgrade_open_source_description">Su suscripción apoya el desarrollo continuo</string>
<string name="upgrade_desktop_access_description">Sincronización con clientes de terceros como Outlook y Apple Reminders</string>

@ -269,7 +269,6 @@
<string name="chat_libera">Liitu kanaliga #tasks Libera Chat\'is</string>
<string name="above_average">Üle keskmise</string>
<string name="app_password_created_at">Loodud: %s</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="premium_record_audio">Salvesta audiomärge</string>
<string name="consent_agree">Nõustun</string>
<string name="default_location">Vaikeasukoht</string>
@ -380,7 +379,6 @@
<string name="sort_start_group">Algusaeg %s</string>
<string name="github_sponsor">Sponsor</string>
<string name="custom_filter_has_subtask">Alamülesannetega</string>
<string name="picker_mode_text">Tekst</string>
<string name="snackbar_task_completed">Ülesanne lõpetatud</string>
<string name="sort_grouping">Grupeerimine</string>
<string name="sort_ascending">Kasvavalt</string>
@ -397,7 +395,6 @@
<string name="follow_reddit">Liitu grupiga r/tasks</string>
<string name="support">Tugi</string>
<string name="tasks_org_account">Tasks.org konto</string>
<string name="picker_mode_clock">Kell</string>
<string name="invite_invalid">Vigane kutse</string>
<string name="completed">Lõpetatud</string>
<string name="enable_reminders">Luba meeldetuletused</string>
@ -722,8 +719,6 @@
<string name="completed_tasks_at_bottom">Nihuta lõpetatud ülesanded alla</string>
<string name="hint_customize_edit_body">Sa võid seda vaadet kohendada väljade ümbertõstmise ja eemaldamise teel</string>
<string name="enable_alarms">Taga õigeaegsed teavitused</string>
<string name="picker_mode_date">Kuupäevavalija vaade</string>
<string name="picker_mode_time">Kellaajavalija vaade</string>
<string name="foreground_location">Asukoht esiplaanil</string>
<string name="upgrade_open_source_description">Sinu tellimus aitab toetada arendustöö jätkamist</string>
<string name="background_location">Asukoht tagaplaanil</string>

@ -608,11 +608,6 @@
<string name="upgrade_more_customization_description">Desblokeatu gai, kolore eta ikono guztiak</string>
<string name="upgrade_more_customization">Pertsonalizazio gehiago</string>
<string name="pro_free_trial">Harpidedun berriek 7 eguneko doako proba jasotzen dute. Ezeztatu edozein unetan</string>
<string name="picker_mode_text">Testua</string>
<string name="picker_mode_clock">Erlojua</string>
<string name="picker_mode_calendar">Egutegia</string>
<string name="picker_mode_time">Denbora hautatzeko modua</string>
<string name="picker_mode_date">Data hautatzeko modua</string>
<string name="next_saturday">Hurrengo larunbata</string>
<string name="next_friday">Hurrengo ostirala</string>
<string name="next_thursday">Hurrengo osteguna</string>

@ -508,11 +508,6 @@
<string name="upgrade_more_customization_description">Avaa kaikki teemat, värit ja kuvakkeet</string>
<string name="upgrade_more_customization">Lisää räätälöintiä</string>
<string name="pro_free_trial">Uudet tilaajat saavat 7 päivän ilmaisen kokeilujakson. Peruuta milloin tahansa</string>
<string name="picker_mode_text">Teksti</string>
<string name="picker_mode_clock">Kello</string>
<string name="picker_mode_calendar">kalenteri</string>
<string name="picker_mode_time">Ajanottotila</string>
<string name="picker_mode_date">Päivämäärän poimintatila</string>
<string name="invite_invalid">Kutsu on mitätön</string>
<string name="invite_awaiting_response">Kutsu odottaa vastausta</string>
<string name="invite_declined">Kutsu hylätty</string>

@ -617,11 +617,6 @@
<string name="invite">Inviter</string>
<string name="email">Courriel</string>
<string name="share_list">Partager la liste</string>
<string name="picker_mode_text">Texte</string>
<string name="picker_mode_clock">Horloge</string>
<string name="picker_mode_calendar">Calendrier</string>
<string name="picker_mode_time">Mode sélecteur de temps</string>
<string name="picker_mode_date">Mode sélecteur de date</string>
<string name="more_options">Plus doptions</string>
<string name="upgrade_open_source_description">Votre abonnement soutient le développement continu</string>
<string name="upgrade_desktop_access_description">Synchronisez avec des clients tiers comme « Outlook » et « Apple Reminders »</string>

@ -369,7 +369,6 @@
<string name="price_per_year">$%s/ano</string>
<string name="migrate_count">Mover %s a Tasks.org</string>
<string name="list_members">Lista de participantes</string>
<string name="picker_mode_date">Modo de selección de data</string>
<string name="caldav_server_unknown">Descoñecido</string>
<string name="caldav_server_other">Outro</string>
<string name="more_options">Máis opcións</string>
@ -529,10 +528,6 @@
<string name="invite">Convidar</string>
<string name="invite_declined">Convite rexeitado</string>
<string name="invite_awaiting_response">Convite en agarda</string>
<string name="picker_mode_time">Modo de selección de hora</string>
<string name="picker_mode_calendar">Calendario</string>
<string name="picker_mode_clock">Reloxo</string>
<string name="picker_mode_text">Texto</string>
<string name="upgrade_desktop_access_description">Sincronizar con clientes de terceiros como Outlook e Appler Reminders</string>
<string name="completed">Finalizada</string>
<string name="completed_tasks_at_bottom">Mover as tarefas finalizadas ao fondo</string>

@ -167,11 +167,6 @@
<string name="upgrade_more_customization_description">Otključaj sve teme, boje i ikone</string>
<string name="upgrade_more_customization">Više prilagođavanja</string>
<string name="pro_free_trial">Novi pretplatnici dobivaju 7-dnevno besplatno probno razdoblje. Otkaži bilo kada</string>
<string name="picker_mode_text">Tekst</string>
<string name="picker_mode_clock">Sat</string>
<string name="picker_mode_calendar">Kalendar</string>
<string name="picker_mode_time">Modus birača vremena</string>
<string name="picker_mode_date">Modus birača datuma</string>
<string name="invite_invalid">Poziv nevaljan</string>
<string name="invite_awaiting_response">Poziv čeka odgovor</string>
<string name="invite_declined">Poziv odbijen</string>

@ -595,11 +595,6 @@
<string name="invite">Meghívás</string>
<string name="email">E-mail</string>
<string name="share_list">Lista megosztása</string>
<string name="picker_mode_text">Szöveg</string>
<string name="picker_mode_clock">Óra</string>
<string name="picker_mode_calendar">Naptár</string>
<string name="picker_mode_time">Időválasztó mód</string>
<string name="picker_mode_date">Dátumválasztó mód</string>
<string name="more_options">Több opció</string>
<string name="upgrade_open_source_description">Az előfizetéseddel a folyamatos fejlesztést támogatod</string>
<string name="upgrade_desktop_access_description">Szinkronizálás harmadik fél megoldásaival, mint az Outlook vagy az Apple Emlékeztetők</string>

@ -589,11 +589,6 @@
<string name="upgrade_more_customization_description">Buka semua tema, warna, dan ikon</string>
<string name="upgrade_more_customization">Lebih banyak kostumisasi</string>
<string name="pro_free_trial">Pelanggan baru menerima percobaan aplikasi gratis selama 7-hari. Batalkan kapan saja</string>
<string name="picker_mode_text">Teks</string>
<string name="picker_mode_clock">Jam</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="picker_mode_time">Mode pengambil waktu</string>
<string name="picker_mode_date">Mode pengambil tanggal</string>
<string name="upgrade_blurb_2">Saya telah menghabiskan ribuan jam bekerja pada Tasks, dan saya mempublikasikan semua kode sumber online secara gratis. Untuk mendukung pekerjaan saya, beberapa fitur memerlukan berlangganan</string>
<string name="upgrade_blurb_1">Hi. Nama saya Alex. Saya adalah pengembang independen dibelakang aplikasi Tasks</string>
<string name="next_saturday">Sabtu Depan</string>

@ -594,11 +594,6 @@
<string name="CFC_startBefore_name">Inizia…</string>
<string name="app_passwords">Password delle app</string>
<string name="widget_show_title">Mostra titolo</string>
<string name="picker_mode_time">Modalità selettore ora</string>
<string name="picker_mode_date">Modalità selettore data</string>
<string name="picker_mode_calendar">Calendario</string>
<string name="picker_mode_clock">Orologio</string>
<string name="picker_mode_text">Testuale</string>
<string name="share_list">Condividi lista</string>
<string name="remove_user_confirmation">%1$s non avrà più accesso a %2$s</string>
<string name="remove_user">Vuoi rimuovere l\'utente\?</string>

@ -615,11 +615,6 @@
<string name="upgrade_more_customization_description">ביטול נעילה של כל ערכות הנושא, הצבעים והסמלים</string>
<string name="upgrade_more_customization">התאמה אישית נוספת</string>
<string name="pro_free_trial">מנויים חדשים מקבלים תקופת ניסיון ללא תשלום למשך 7 ימים. ביטול בכל עת</string>
<string name="picker_mode_text">טקסט</string>
<string name="picker_mode_clock">שָׁעוֹן</string>
<string name="picker_mode_calendar">לוח שנה</string>
<string name="picker_mode_time">מצב בורר זמן</string>
<string name="picker_mode_date">מצב בוחר תאריכים</string>
<string name="invite_invalid">הזמנה לא חוקית</string>
<string name="invite_awaiting_response">הזמן תגובה ממתינה</string>
<string name="invite_declined">ההזמנה נדחתה</string>

@ -484,7 +484,6 @@
<string name="authentication_required">認証が必要です</string>
<string name="share_list">リストを共有</string>
<string name="markdown">マークダウン</string>
<string name="picker_mode_date">日付選択の方法</string>
<string name="auto_dismiss_datetime_widget">ウィジェット</string>
<string name="lists">リスト</string>
<string name="migrating_tasks">タスクを移行する</string>
@ -571,8 +570,6 @@
<string name="tasks_org_account_required">Tasks.org のアカウントが必要です</string>
<string name="account_not_included">「価格はあなた次第」でのサブスクリプションには含まれていません</string>
<string name="list_members">リストメンバー</string>
<string name="picker_mode_text">文字</string>
<string name="picker_mode_time">時間選択の方法</string>
<string name="remove_user_confirmation">%1$s は %2$s にアクセスできなくなります</string>
<string name="invite_awaiting_response">応答待ちの招待</string>
<string name="enable_reminders">リマインダーを有効にする</string>
@ -616,8 +613,6 @@
<string name="troubleshooting">トラブルシューティング</string>
<string name="app_passwords_more_info">タスクやカレンダーをサードパーティ製のデスクトップアプリやモバイルアプリと同期します。詳しくはここをタップ</string>
<string name="support">サポート</string>
<string name="picker_mode_clock">時計</string>
<string name="picker_mode_calendar">カレンダー</string>
<string name="permission_read_tasks">Tasks データベースへの完全なアクセス</string>
<string name="auto_dismiss_datetime">日時選択画面を自動で閉じる</string>
<string name="chip_appearance_icon_only">アイコンのみ</string>

@ -567,12 +567,7 @@
<string name="upgrade_more_customization_description">모든 테마, 색상, 아이콘 사용</string>
<string name="upgrade_more_customization">더 다양한 맞춤설정</string>
<string name="pro_free_trial">새 구독자는 7일간 무료 체험이 가능합니다. 언제라도 취소할 수 있습니다</string>
<string name="picker_mode_text">글자</string>
<string name="app_passwords_more_info">타사 데스크탑 및 모바일 앱으로 할일과 달력을 동기화합니다. 자세한 정보는 여기를 탭하세요</string>
<string name="picker_mode_clock">시계</string>
<string name="picker_mode_calendar">달력</string>
<string name="picker_mode_time">시간 선택상자 모드</string>
<string name="picker_mode_date">날짜 선택상자 모드</string>
<string name="invite_invalid">유효하지 않은 초대</string>
<string name="invite_awaiting_response">응답 대기중인 초대</string>
<string name="invite_declined">초대 거절</string>

@ -488,9 +488,6 @@
<string name="invite_declined">Kvietimas atmestas</string>
<string name="invite_awaiting_response">Kvietimas laukia atsakymo</string>
<string name="invite_invalid">Kvietimas negalioja</string>
<string name="picker_mode_calendar">Kalendorius</string>
<string name="picker_mode_clock">Laikrodis</string>
<string name="picker_mode_text">Tekstas</string>
<string name="pro_free_trial">Naujiems prenumeratoriams suteikiamas 7 dienų nemokamas bandomasis laikotarpis. Atšaukite bet kuriuo metu</string>
<string name="upgrade_more_customization">Daugiau tinkinimo</string>
<string name="upgrade_tasks_org_account_description">Sinchronizuokite su Tasks.org ir bendradarbiaukite su kitais naudotojais</string>
@ -597,8 +594,6 @@
<string name="automatic_backups">Automatinės atsarginės kopijos</string>
<string name="permission_read_tasks">Pilna prieiga prie Tasks duomenų bazės</string>
<string name="reset_sort_order">Iš naujo nustatyti rūšiavimo tvarką</string>
<string name="picker_mode_time">Laiko rinkiklio režimas</string>
<string name="picker_mode_date">Datos rinkiklio režimas</string>
<string name="local_lists">Vietiniai sąrašai</string>
<string name="open_last_viewed_list">Atidaryti paskutinį peržiūrėtą sąrašą</string>
<string name="on_launch">Paleidžiant</string>

@ -605,11 +605,6 @@
<string name="upgrade_more_customization_description">Lås opp alle temaer, farger og ikoner</string>
<string name="upgrade_more_customization">Mer tilpasning</string>
<string name="pro_free_trial">Nye abonnenter får en 7-dagers gratis prøveperiode. Avbryt når som helst</string>
<string name="picker_mode_text">Tekst</string>
<string name="picker_mode_clock">klokke</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="picker_mode_time">Modus for tidsvelger</string>
<string name="picker_mode_date">Datovelgermodus</string>
<string name="invite_invalid">Invitasjon ugyldig</string>
<string name="invite_awaiting_response">Inviter venter på svar</string>
<string name="invite_declined">Invitasjon avslått</string>

@ -595,11 +595,6 @@
<string name="invite_awaiting_response">Uitnodiging wacht op reactie</string>
<string name="invite_declined">Uitnodiging afgewezen</string>
<string name="email">E-mail</string>
<string name="picker_mode_text">Tekst</string>
<string name="picker_mode_clock">Klok</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="picker_mode_time">Tijdkiezer-modus</string>
<string name="picker_mode_date">Datumkiezer-modus</string>
<string name="upgrade_more_customization">Meer maatwerk</string>
<string name="upgrade_more_customization_description">Alle thema\'s, kleuren en pictogrammen ontgrendelen</string>
<string name="more_options">Meer opties</string>

@ -109,8 +109,6 @@
<string name="open_source">ଖୋଲା ଉତ୍ସ</string>
<string name="invite">ନିମନ୍ତ୍ରଣ ପଠାଇବା</string>
<string name="invite_invalid">ନିମନ୍ତ୍ରଣ ଅମାନ୍ୟ ଅଟେ</string>
<string name="picker_mode_calendar">କ୍ୟାଲେଣ୍ଡର</string>
<string name="picker_mode_clock">ଘଡ଼ି</string>
<string name="widget_show_title">ଆଖ୍ୟା ଦେଖାଅ</string>
<string name="SSD_sort_my_order">ମୋର କ୍ରମ</string>
<string name="SSD_sort_start">ଆରମ୍ଭ ତାରିଖ ଅନୁଯାୟୀ</string>

@ -614,11 +614,6 @@
<string name="upgrade_more_customization_description">Odblokuj wszystkie motywy, kolory oraz ikony</string>
<string name="upgrade_more_customization">Więcej możliwości konfiguracji</string>
<string name="pro_free_trial">Nowi subskrybenci otrzymują 7-dniowy, darmowy okres próbny. Można anulować w dowolnym momencie</string>
<string name="picker_mode_text">Tekst</string>
<string name="picker_mode_clock">Zegar</string>
<string name="picker_mode_calendar">Kalendarz</string>
<string name="picker_mode_time">Tryb Time picker</string>
<string name="picker_mode_date">Tryb selektora dat</string>
<string name="invite_invalid">Zaproszenie nieważne</string>
<string name="invite_awaiting_response">Zaproszenie oczekuje na odpowiedź</string>
<string name="invite_declined">Zaproszenie odrzucone</string>

@ -564,11 +564,6 @@
<string name="upgrade_more_customization_description">Desbloqueie todos os temas, cores e ícones</string>
<string name="upgrade_more_customization">Mais customização</string>
<string name="pro_free_trial">Novos assinantes recebem 7 dias de teste grátis. Cancele a qualquer momento</string>
<string name="picker_mode_text">Texto</string>
<string name="picker_mode_clock">Relógio</string>
<string name="picker_mode_calendar">Calendário</string>
<string name="picker_mode_time">Modo de escolher hora</string>
<string name="picker_mode_date">Modo de escolher data</string>
<string name="invite_invalid">Convite inválido</string>
<string name="invite_awaiting_response">Convite aguardando resposta</string>
<string name="invite_declined">Convite cancelado</string>

@ -539,11 +539,6 @@
<string name="upgrade_more_customization_description">Desbloqueie todos os temas, cores e ícones</string>
<string name="upgrade_more_customization">Mais personalizações</string>
<string name="pro_free_trial">Os novos subscritores recebem 7 dias de teste grátis. Cancele a qualquer momento</string>
<string name="picker_mode_text">Texto</string>
<string name="picker_mode_clock">Relógio</string>
<string name="picker_mode_calendar">Calendário</string>
<string name="picker_mode_time">Modo de escolher hora</string>
<string name="picker_mode_date">Modo de escolher data</string>
<string name="invite_invalid">Convite inválido</string>
<string name="invite_awaiting_response">Convite a aguardar resposta</string>
<string name="invite_declined">Convite cancelado</string>

@ -7,7 +7,6 @@
<string name="custom_filter_or">SAU</string>
<string name="filters">Filtre</string>
<string name="email">E-mail</string>
<string name="picker_mode_calendar">Calendar</string>
<string name="compact">Compact</string>
<string name="TEA_timer_est">Estim. %s</string>
<string name="TEA_control_gcal">Calendar</string>
@ -23,10 +22,6 @@
<string name="upgrade_more_customization_description">Deblochează toate temele, culorile și pictogramele</string>
<string name="upgrade_more_customization">Mai multă personalizare</string>
<string name="pro_free_trial">Noii abonați beneficiază de o perioadă de încercare gratuită de 7 zile. Anulare în orice moment</string>
<string name="picker_mode_text">Text</string>
<string name="picker_mode_clock">Ceas</string>
<string name="picker_mode_time">Modul de selectare a timpului</string>
<string name="picker_mode_date">Modul de selectare a datei</string>
<string name="invite_invalid">Invitație nevalabilă</string>
<string name="invite_awaiting_response">Invitație în așteptarea răspunsului</string>
<string name="invite_declined">Invitație refuzată</string>

@ -613,11 +613,6 @@
<string name="upgrade_more_customization_description">Разблокировать все темы, цвета и иконки</string>
<string name="upgrade_more_customization">Больше настроек</string>
<string name="pro_free_trial">Новые подписчики получают 7-дневный бесплатный пробный период. Отмена возможна в любое время</string>
<string name="picker_mode_text">Текст</string>
<string name="picker_mode_clock">Часы</string>
<string name="picker_mode_calendar">Календарь</string>
<string name="picker_mode_time">Режим выбора времени</string>
<string name="picker_mode_date">Режим выбора даты</string>
<string name="invite_invalid">Приглашение недействительно</string>
<string name="invite_awaiting_response">Приглашение в ожидании ответа</string>
<string name="invite_declined">Приглашение отклонено</string>

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="github_sponsor">අනුග්‍රාහකයා</string>
<string name="picker_mode_date">දින තේරීම් ආකාරය</string>
<string name="invite_invalid">ආරාධනය අවලංගුයි</string>
<string name="share_list">ලැයිස්තුව බෙදාගන්න</string>
<string name="issue_tracker">දෝෂ සෙවීම</string>
@ -65,9 +64,6 @@
<string name="upgrade_more_customization_description">සියලුම තේමාවන්, වර්ණ සහ අයිකන අගුළු ඇරීම</string>
<string name="upgrade_more_customization">තවත් අභිරුචිකරණය</string>
<string name="pro_free_trial">නව ග්‍රාහකයින්ට දින 7 ක නොමිලේ අත්හදා බැලීම් කාලයක් ලැබේ. ඕනෑම වේලාවක අවලංගු කරන්න</string>
<string name="picker_mode_text">පෙළ</string>
<string name="picker_mode_clock">ඔරලෝසුව</string>
<string name="picker_mode_calendar">දින දර්ශනය</string>
<string name="invite_declined">ආරාධනය ප්‍රතික්ෂේප විය</string>
<string name="invite">ආරාධනා කරන්න</string>
<string name="email">විද්යුත් තැපෑල</string>
@ -610,7 +606,6 @@
<string name="repeats_single_on">%1$s, %2$s පුනරාවර්තනය වේ</string>
<string name="markdown_description">මාතෘකාව සහ විස්තරය තුළ ලකුණු කිරීම සක්‍රිය කරන්න</string>
<string name="markdown">ලකුණු කිරීම</string>
<string name="picker_mode_time">කාලය තෝරාගැනීම් මාදිලිය</string>
<string name="invite_awaiting_response">ප්‍රතිචාරයක් බලාපොරොත්තුවෙන් ඇති ආරාධන</string>
<string name="list_members">සාමාජික ලැයිස්තුව</string>
<string name="migrating_tasks">සංක්‍රමණික කාර්යයන්</string>

@ -705,7 +705,6 @@
<string name="app_passwords">Heslá aplikácie</string>
<string name="app_passwords_more_info">Synchronizujte svoje úlohy a kalendáre s desktopovými a mobilnými aplikáciami tretích strán. Pre viac informácii kliknite sem</string>
<string name="invite_invalid">Neplatná pozvánka</string>
<string name="picker_mode_clock">Hodiny</string>
<string name="caldav_server_unknown">Neznámy</string>
<string name="consent_agree">Súhlasím</string>
<string name="sort_sorting">Triedenie</string>
@ -725,11 +724,7 @@
<string name="invite_awaiting_response">Pozvánka čaká na odpoveď</string>
<string name="invite_declined">Pozvánka bola odmietnutá</string>
<string name="upgrade_tasks_org_account_description">Synchronizujte s Tasks.org a spolupracujte s ostatnými používateľmi</string>
<string name="picker_mode_text">Text</string>
<string name="remove_user">Odobrať používateľa?</string>
<string name="picker_mode_date">Režim výberu dátumu</string>
<string name="picker_mode_time">Režim výberu času</string>
<string name="picker_mode_calendar">Kalendár</string>
<string name="pro_free_trial">Noví predplatitelia dostanú 7 dní na bezplatné otestovanie. Predplatné je možné kedykoľvek zrušiť</string>
<string name="upgrade_more_customization">Ďalšie prispôsobenie</string>
<string name="upgrade_more_customization_description">Odomknúť všetky motívy, farby a ikony</string>

@ -443,11 +443,6 @@
<string name="upgrade_more_customization_description">Lås upp alla teman, färger och ikoner</string>
<string name="upgrade_more_customization">Mer anpassning</string>
<string name="pro_free_trial">Nya prenumeranter får en gratis provperiod på 7 dagar. Avbryt när som helst</string>
<string name="picker_mode_text">Text</string>
<string name="picker_mode_clock">Klocka</string>
<string name="picker_mode_calendar">Kalender</string>
<string name="picker_mode_time">Tidsväljarläge</string>
<string name="picker_mode_date">Datumväljarläge</string>
<string name="invite_invalid">Inbjudan ogiltig</string>
<string name="invite_awaiting_response">Inbjudan väntar på svar</string>
<string name="invite_declined">Inbjudan avfärdad</string>

@ -40,11 +40,6 @@
<string name="more_options">ตัวเลือกเพิ่มเติม</string>
<string name="upgrade_desktop_access">การเข้าถึงเดสก์ท็อป</string>
<string name="upgrade_tasks_org_account_description">ซิงค์กับ Tasks.org และทํางานร่วมกับผู้ใช้รายอื่น</string>
<string name="picker_mode_text">ข้อความ</string>
<string name="picker_mode_clock">นาฬิกา</string>
<string name="picker_mode_calendar">ปฏิทิน</string>
<string name="picker_mode_time">โหมดตัวใช้เลือกเวลา</string>
<string name="picker_mode_date">โหมดตัวใช้เลือกวันที่</string>
<string name="invite_invalid">การเชิญไม่ถูกต้อง</string>
<string name="invite_awaiting_response">คําเชิญที่กําลังรอการตอบกลับ</string>
<string name="invite_declined">ปฏิเสธคำเชิญ</string>

@ -608,11 +608,6 @@
<string name="upgrade_tasks_org_account_description">Tasks.org ile eşzamanla ve diğer kullanıcılarla ortak çalış</string>
<string name="upgrade_more_customization">Daha çok özelleştirme</string>
<string name="pro_free_trial">Yeni aboneler 7 günlük sınama süresi kazanır. İstendiğinde iptal edilir</string>
<string name="picker_mode_text">Metin</string>
<string name="picker_mode_clock">Saat</string>
<string name="picker_mode_calendar">Takvim</string>
<string name="picker_mode_time">Zaman seçici kipi</string>
<string name="picker_mode_date">Tarih seçici kipi</string>
<string name="next_friday">Sonraki Cma</string>
<string name="next_saturday">Sonraki Cts</string>
<string name="next_thursday">Sonraki Per</string>

@ -615,11 +615,6 @@
<string name="invite">Запросити</string>
<string name="email">Е-пошта</string>
<string name="share_list">Поділитися списком</string>
<string name="picker_mode_text">Текст</string>
<string name="picker_mode_clock">Годинник</string>
<string name="picker_mode_calendar">Календар</string>
<string name="picker_mode_time">Режим вибору часу</string>
<string name="picker_mode_date">Режим вибору дати</string>
<string name="more_options">Додаткові параметри</string>
<string name="upgrade_open_source_description">Ваша передплата підтримує постійний розвиток</string>
<string name="upgrade_desktop_access_description">Синхронізація зі сторонніми клієнтами, наприклад Outlook і Apple Нагадування</string>

@ -66,11 +66,6 @@
<string name="upgrade_more_customization_description">Mở khoá tất cả chủ đề, màu sắc, và biểu tượng</string>
<string name="upgrade_more_customization">Nhiều tuỳ biến hơn</string>
<string name="pro_free_trial">Những người đăng ký mới sẽ nhận khoảng thời gian dùng thử 7 ngày miễn phí. Huỷ vào bất kỳ lúc nào</string>
<string name="picker_mode_text">Văn bản</string>
<string name="picker_mode_clock">Đồng hồ</string>
<string name="picker_mode_calendar">Lịch</string>
<string name="picker_mode_time">Chế độ trình chọn thời gian</string>
<string name="picker_mode_date">Chế độ trình chọn ngày</string>
<string name="invite_invalid">Lời mời không hợp lệ</string>
<string name="invite">Lời mời</string>
<string name="invite_awaiting_response">Lời mời đang chờ phản hồi</string>

@ -589,11 +589,6 @@
<string name="invite">邀请</string>
<string name="email">电子邮件</string>
<string name="share_list">分享列表</string>
<string name="picker_mode_calendar">日历</string>
<string name="picker_mode_text">文本</string>
<string name="picker_mode_clock">时钟</string>
<string name="picker_mode_time">时间选择器模式</string>
<string name="picker_mode_date">日期选择器模式</string>
<string name="more_options">更多选项</string>
<string name="upgrade_open_source_description">你的订阅支持持续开发</string>
<string name="upgrade_desktop_access_description">与 Outlook 和 Apple Reminders 等第三方客户端同步</string>

@ -568,7 +568,6 @@
<string name="completed_tasks_at_bottom">將已完成的任務移至底部</string>
<string name="repeat_monthly_on_the_nth_weekday">每月於 %1$s %2$s</string>
<string name="background_location_permission_required">Tasks 收集位置資料以啟用基於位置的提醒,即使應用程式關閉或未使用。</string>
<string name="picker_mode_clock">時鐘</string>
<string name="upgrade_more_customization_description">解鎖所有主題、顏色和圖示</string>
<string name="back">返回</string>
<string name="place_settings">位置設定</string>
@ -576,7 +575,6 @@
<string name="pro_dashclock_extension">Dashclock 擴充</string>
<string name="auto_dismiss_datetime_edit_summary">選擇任務編輯時自動關閉</string>
<string name="remove_user_confirmation">%1$s 將不再存取 %2$s 的資料庫</string>
<string name="picker_mode_time">時間選取器模式</string>
<string name="snackbar_task_completed">任務已完成</string>
<string name="sort_created_group">建立於 %s</string>
<string name="invite_declined">邀請已拒絕</string>
@ -589,7 +587,6 @@
<string name="above_average">高於平均</string>
<string name="dismiss">關閉</string>
<string name="custom_notification">自訂通知</string>
<string name="picker_mode_calendar">行事曆</string>
<string name="custom_filter_has_reminder">有提醒</string>
<string name="no_google_play_subscription">沒有符合資格的 Google Play 訂閱</string>
<string name="follow_reddit">加入 r/tasks</string>
@ -640,8 +637,6 @@
<string name="pro_free_trial">新訂閱者享有 7 天免費試用。隨時取消</string>
<string name="list_members">清單成員</string>
<string name="invite_invalid">邀請無效</string>
<string name="picker_mode_date">日期選擇模式</string>
<string name="picker_mode_text">文字</string>
<string name="upgrade_tasks_org_account_description">與 Tasks.org 同步,並與其他用戶協作</string>
<string name="upgrade_more_customization">更多自訂</string>
<string name="local_lists">本機清單</string>

@ -127,16 +127,6 @@
<item>2</item>
</string-array>
<string-array name="date_picker_modes">
<item>@string/picker_mode_calendar</item>
<item>@string/picker_mode_text</item>
</string-array>
<string-array name="time_picker_modes">
<item>@string/picker_mode_clock</item>
<item>@string/picker_mode_text</item>
</string-array>
<string-array name="two_values">
<item>0</item>
<item>1</item>

@ -679,11 +679,6 @@ File %1$s contained %2$s.\n\n
<string name="invite_declined">Invite declined</string>
<string name="invite_awaiting_response">Invite awaiting response</string>
<string name="invite_invalid">Invite invalid</string>
<string name="picker_mode_date">Date picker mode</string>
<string name="picker_mode_time">Time picker mode</string>
<string name="picker_mode_calendar">Calendar</string>
<string name="picker_mode_clock">Clock</string>
<string name="picker_mode_text">Text</string>
<string name="pro_free_trial">New subscribers receive a 7-day free trial. Cancel at any time</string>
<string name="upgrade_more_customization">More customization</string>
<string name="upgrade_more_customization_description">Unlock all themes, colors, and icons</string>

@ -8,23 +8,6 @@
android:key="@string/p_always_display_full_date"
android:title="@string/always_display_full_date" />
<ListPreference
android:defaultValue="0"
android:key="@string/p_picker_mode_date"
android:title="@string/picker_mode_date"
android:entries="@array/date_picker_modes"
android:entryValues="@array/two_values"
android:summary="%s"
app:allowDividerAbove="true" />
<ListPreference
android:defaultValue="0"
android:key="@string/p_picker_mode_time"
android:title="@string/picker_mode_time"
android:entries="@array/time_picker_modes"
android:entryValues="@array/two_values"
android:summary="%s" />
<org.tasks.ui.TimePreference
android:defaultValue="@integer/default_morning"
android:key="@string/p_date_shortcut_morning"

Loading…
Cancel
Save