From 40d831f7da10e27e75a3ce35ec20a71988a91152 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Mon, 15 Mar 2021 17:22:04 -0500 Subject: [PATCH] Material components date and time pickers --- app/build.gradle.kts | 1 - app/licenses.yml | 6 - app/src/main/assets/licenses.json | 14 --- .../activities/DateAndTimePickerActivity.java | 85 -------------- .../activities/DateAndTimePickerActivity.kt | 106 ++++++++++++++++++ .../java/org/tasks/dialogs/DateTimePicker.kt | 2 +- .../org/tasks/dialogs/MyDatePickerDialog.java | 93 --------------- .../org/tasks/dialogs/MyDatePickerDialog.kt | 76 +++++++++++++ .../org/tasks/dialogs/MyTimePickerDialog.java | 91 --------------- .../org/tasks/dialogs/MyTimePickerDialog.kt | 86 ++++++++++++++ .../java/org/tasks/dialogs/StartDatePicker.kt | 2 +- .../preferences/fragments/DateAndTime.kt | 2 +- .../preferences/fragments/Notifications.kt | 2 +- app/src/main/res/color/clock_text_color.xml | 20 ++++ .../mtrl_choice_chip_background_color.xml | 26 +++++ .../res/color/mtrl_choice_chip_text_color.xml | 27 +++++ .../res/color/mtrl_filled_stroke_color.xml | 23 ++++ .../mtrl_text_btn_text_color_selector.xml | 23 ++++ app/src/main/res/values/keys.xml | 2 - app/src/main/res/values/styles.xml | 60 +++++++++- app/src/main/res/values/theme.xml | 4 +- deps_fdroid.txt | 3 - deps_googleplay.txt | 3 - 23 files changed, 452 insertions(+), 305 deletions(-) delete mode 100644 app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.java create mode 100644 app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.kt delete mode 100644 app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.java create mode 100644 app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.kt delete mode 100644 app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.java create mode 100644 app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.kt create mode 100644 app/src/main/res/color/clock_text_color.xml create mode 100644 app/src/main/res/color/mtrl_choice_chip_background_color.xml create mode 100644 app/src/main/res/color/mtrl_choice_chip_text_color.xml create mode 100644 app/src/main/res/color/mtrl_filled_stroke_color.xml create mode 100644 app/src/main/res/color/mtrl_text_btn_text_color_selector.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 14caf48cc..e3d5a1ce9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -216,7 +216,6 @@ dependencies { implementation("com.rubiconproject.oss:jchronic:0.2.6") { isTransitive = false } - implementation("com.wdullaer:materialdatetimepicker:4.2.3") implementation("me.leolin:ShortcutBadger:1.1.22@aar") implementation("com.google.apis:google-api-services-tasks:v1-rev20210109-1.31.0") implementation("com.google.apis:google-api-services-drive:v3-rev20210228-1.31.0") diff --git a/app/licenses.yml b/app/licenses.yml index efbf46599..06effa7c3 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -159,12 +159,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: https://github.com/JetBrains/java-annotations -- artifact: com.wdullaer:materialdatetimepicker:+ - name: MaterialDateTimePicker - copyrightHolder: Wouter Dullaert - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/wdullaer/MaterialDateTimePicker - artifact: org.apache.commons:commons-lang3:+ name: Apache Commons Lang copyrightHolder: The Apache Software Foundation diff --git a/app/src/main/assets/licenses.json b/app/src/main/assets/licenses.json index a11eca5e5..aa8655440 100644 --- a/app/src/main/assets/licenses.json +++ b/app/src/main/assets/licenses.json @@ -385,20 +385,6 @@ "url": "https://github.com/JetBrains/java-annotations", "libraryName": "JetBrains Java Annotations" }, - { - "artifactId": { - "name": "materialdatetimepicker", - "group": "com.wdullaer", - "version": "+" - }, - "copyrightHolder": "Wouter Dullaert", - "copyrightStatement": "Copyright © Wouter Dullaert. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/wdullaer/MaterialDateTimePicker", - "libraryName": "MaterialDateTimePicker" - }, { "artifactId": { "name": "commons-lang3", diff --git a/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.java b/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.java deleted file mode 100644 index 4c40aa318..000000000 --- a/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.java +++ /dev/null @@ -1,85 +0,0 @@ -package org.tasks.activities; - -import static org.tasks.dialogs.MyDatePickerDialog.newDatePicker; -import static org.tasks.dialogs.MyTimePickerDialog.newTimePicker; -import static org.tasks.time.DateTimeUtils.currentTimeMillis; - -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import dagger.hilt.android.AndroidEntryPoint; -import javax.inject.Inject; -import org.tasks.dialogs.MyDatePickerDialog; -import org.tasks.dialogs.MyTimePickerDialog; -import org.tasks.injection.InjectingAppCompatActivity; -import org.tasks.preferences.Preferences; -import org.tasks.themes.ThemeAccent; -import org.tasks.time.DateTime; - -@AndroidEntryPoint -public class DateAndTimePickerActivity extends InjectingAppCompatActivity - implements MyDatePickerDialog.DatePickerCallback, MyTimePickerDialog.TimePickerCallback { - - public static final String EXTRA_TIMESTAMP = "extra_timestamp"; - private static final String FRAG_TAG_DATE_PICKER = "frag_tag_date_picker"; - private static final String FRAG_TAG_TIME_PICKER = "frag_tag_time_picker"; - private static final String EXTRA_DATE_SELECTED = "extra_date_selected"; - @Inject ThemeAccent themeAccent; - @Inject Preferences preferences; - - private DateTime initial; - private boolean dateSelected; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - initial = new DateTime(getIntent().getLongExtra(EXTRA_TIMESTAMP, currentTimeMillis())); - - if (savedInstanceState != null) { - dateSelected = savedInstanceState.getBoolean(EXTRA_DATE_SELECTED, false); - if (dateSelected) { - return; - } - } - - themeAccent.applyStyle(getTheme()); - - androidx.fragment.app.FragmentManager fragmentManager = getSupportFragmentManager(); - if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) { - newDatePicker(null, 0, initial.getMillis()) - .show(getSupportFragmentManager(), FRAG_TAG_DATE_PICKER); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(EXTRA_DATE_SELECTED, dateSelected); - } - - @Override - public void onDatePicked(DialogInterface dialog, long timestamp) { - if (timestamp == MyDatePickerDialog.NO_DATE) { - finish(); - } else { - dialog.dismiss(); - dateSelected = true; - newTimePicker( - null, - 0, - new DateTime(timestamp).withMillisOfDay(initial.getMillisOfDay()).getMillis()) - .show(getSupportFragmentManager(), FRAG_TAG_TIME_PICKER); - } - } - - @Override - public void onTimePicked(long timestamp) { - if (timestamp != MyTimePickerDialog.NO_TIME) { - final Intent data = new Intent(); - data.putExtra(MyTimePickerDialog.EXTRA_TIMESTAMP, timestamp); - setResult(RESULT_OK, data); - } - finish(); - } -} diff --git a/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.kt b/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.kt new file mode 100644 index 000000000..8c8ac6e12 --- /dev/null +++ b/app/src/main/java/org/tasks/activities/DateAndTimePickerActivity.kt @@ -0,0 +1,106 @@ +package org.tasks.activities + +import android.content.Intent +import android.os.Bundle +import com.google.android.material.datepicker.MaterialDatePicker +import com.google.android.material.timepicker.MaterialTimePicker +import dagger.hilt.android.AndroidEntryPoint +import org.tasks.dialogs.MyDatePickerDialog.Companion.newDatePicker +import org.tasks.dialogs.MyTimePickerDialog +import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker +import org.tasks.injection.InjectingAppCompatActivity +import org.tasks.preferences.Preferences +import org.tasks.themes.ThemeAccent +import org.tasks.time.DateTime +import org.tasks.time.DateTimeUtils.currentTimeMillis +import javax.inject.Inject + +@AndroidEntryPoint +class DateAndTimePickerActivity : InjectingAppCompatActivity() { + @Inject lateinit var themeAccent: ThemeAccent + @Inject lateinit var preferences: Preferences + + private var initial: DateTime? = null + private var dateSelected: DateTime? = null + + 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) } + themeAccent.applyStyle(theme) + 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 + ?: newDatePicker(date.millis).apply { + show(supportFragmentManager, FRAG_TAG_DATE_PICKER) + } + 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 + ).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.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" + } +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt b/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt index a24db5bcb..a4688380c 100644 --- a/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt +++ b/app/src/main/java/org/tasks/dialogs/DateTimePicker.kt @@ -21,7 +21,7 @@ import org.tasks.R import org.tasks.databinding.DialogDateTimePickerBinding import org.tasks.date.DateTimeUtils.newDateTime import org.tasks.date.DateTimeUtils.toDateTime -import org.tasks.dialogs.MyTimePickerDialog.newTimePicker +import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker import org.tasks.locale.Locale import org.tasks.notifications.NotificationManager import org.tasks.time.DateTime diff --git a/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.java b/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.java deleted file mode 100644 index 9ac28e786..000000000 --- a/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.java +++ /dev/null @@ -1,93 +0,0 @@ -package org.tasks.dialogs; - -import static android.app.Activity.RESULT_CANCELED; -import static android.app.Activity.RESULT_OK; -import static org.tasks.time.DateTimeUtils.currentTimeMillis; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; -import com.wdullaer.materialdatetimepicker.date.DatePickerDialog.OnDateSetListener; -import org.tasks.R; -import org.tasks.preferences.Preferences; -import org.tasks.time.DateTime; - -public class MyDatePickerDialog extends DatePickerDialog implements OnDateSetListener { - - public static final String EXTRA_TIMESTAMP = "extra_timestamp"; - public static final int NO_DATE = -1; - - public static MyDatePickerDialog newDatePicker(Fragment target, int rc, long initial) { - Bundle arguments = new Bundle(); - arguments.putLong(EXTRA_TIMESTAMP, initial); - MyDatePickerDialog dialog = new MyDatePickerDialog(); - dialog.setArguments(arguments); - dialog.setTargetFragment(target, rc); - return dialog; - } - - public interface DatePickerCallback{ // TODO: remove this after removing DateAndTimePickerActivity - void onDatePicked(DialogInterface dialog, long timestamp); - } - - private DatePickerCallback callback; - - @Override - public void onCreate(Bundle savedInstanceState) { - if (savedInstanceState == null) { - long timestamp = getArguments().getLong(EXTRA_TIMESTAMP, currentTimeMillis()); - DateTime initial = (timestamp > 0 ? new DateTime(timestamp) : new DateTime()).startOfDay(); - initialize( - null, - initial.getYear(), - initial.getMonthOfYear() - 1, - initial.getDayOfMonth()); - setVersion(DatePickerDialog.Version.VERSION_2); - int firstDayOfWeek = new Preferences(getContext()).getFirstDayOfWeek(); - if (firstDayOfWeek >= 1 && firstDayOfWeek <= 7) { - setFirstDayOfWeek(firstDayOfWeek); - } - setThemeDark(getResources().getBoolean(R.bool.is_dark)); // TODO: remove this after removing DateAndTimePickerActivity - } - - setOnDateSetListener(this); - - super.onCreate(savedInstanceState); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - - if (context instanceof DatePickerCallback) { - callback = (DatePickerCallback) context; - } - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - if (getTargetFragment() == null) { - callback.onDatePicked(dialog, NO_DATE); - } else { - getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_CANCELED, null); - } - } - - @Override - public void onDateSet(DatePickerDialog view, int year, int monthOfYear, int dayOfMonth) { - long result = new DateTime(year, monthOfYear + 1, dayOfMonth).getMillis(); - if (getTargetFragment() == null) { - callback.onDatePicked(getDialog(), result); - } else { - Intent data = new Intent(); - data.putExtra(EXTRA_TIMESTAMP, result); - getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_OK, data); - } - } -} diff --git a/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.kt b/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.kt new file mode 100644 index 000000000..41b6e419e --- /dev/null +++ b/app/src/main/java/org/tasks/dialogs/MyDatePickerDialog.kt @@ -0,0 +1,76 @@ +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 androidx.fragment.app.Fragment +import com.google.android.material.datepicker.MaterialDatePicker +import com.todoroo.andlib.utility.DateUtilities +import org.tasks.time.DateTime +import org.tasks.time.DateTimeUtils.currentTimeMillis +import org.tasks.time.DateTimeUtils.startOfDay + +class MyDatePickerDialog : DialogFragment() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val fragment = + (childFragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) as? MaterialDatePicker) + ?: newDatePicker(initial) + .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) ?: DateUtilities.now().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(target: Fragment, rc: Int, initial: Long) = + MyDatePickerDialog().apply { + arguments = Bundle().apply { + putLong(EXTRA_TIMESTAMP, initial) + } + setTargetFragment(target, rc) + } + + @JvmStatic + fun newDatePicker(initial: Long) = MaterialDatePicker.Builder.datePicker() + // TODO: setInputMode for calendar or text + // TODO: figure out hack for first day of week + .setSelection(if (initial > 0) initial else currentTimeMillis()) + .build() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.java b/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.java deleted file mode 100644 index 602d34b5e..000000000 --- a/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.tasks.dialogs; - -import static android.app.Activity.RESULT_CANCELED; -import static android.app.Activity.RESULT_OK; -import static org.tasks.date.DateTimeUtils.newDateTime; -import static org.tasks.time.DateTimeUtils.currentTimeMillis; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.os.Bundle; -import android.text.format.DateFormat; -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; -import com.wdullaer.materialdatetimepicker.time.TimePickerDialog.OnTimeSetListener; -import org.tasks.R; -import org.tasks.time.DateTime; - -public class MyTimePickerDialog extends TimePickerDialog implements OnTimeSetListener { - - public static final String EXTRA_TIMESTAMP = "extra_timestamp"; - public static final int NO_TIME = -1; - - public static MyTimePickerDialog newTimePicker(Fragment target, int rc, long initial) { - Bundle arguments = new Bundle(); - arguments.putLong(EXTRA_TIMESTAMP, initial); - MyTimePickerDialog dialog = new MyTimePickerDialog(); - dialog.setArguments(arguments); - dialog.setTargetFragment(target, rc); - return dialog; - } - - public interface TimePickerCallback { // TODO: remove this after removing DateAndTimePickerActivity - void onTimePicked(long timestamp); - } - - private DateTime initial; - private TimePickerCallback callback; - - @Override - public void onCreate(Bundle savedInstanceState) { - initial = newDateTime(getArguments().getLong(EXTRA_TIMESTAMP, currentTimeMillis())); - - if (savedInstanceState == null) { - initialize( - null, - initial.getHourOfDay(), - initial.getMinuteOfHour(), - 0, - DateFormat.is24HourFormat(getContext())); - setThemeDark(getResources().getBoolean(R.bool.is_dark)); // TODO: remove this after removing DateAndTimePickerActivity - } - - setOnTimeSetListener(this); - - super.onCreate(savedInstanceState); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - - if (context instanceof TimePickerCallback) { - callback = (TimePickerCallback) context; - } - } - - @Override - public void onCancel(DialogInterface dialog) { - super.onCancel(dialog); - - if (getTargetFragment() == null) { - callback.onTimePicked(NO_TIME); - } else { - getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_CANCELED, null); - } - } - - @Override - public void onTimeSet(TimePickerDialog view, int hours, int minutes, int second) { - long result = initial.startOfDay().withHourOfDay(hours).withMinuteOfHour(minutes).getMillis(); - if (getTargetFragment() == null) { - callback.onTimePicked(result); - } else { - Intent data = new Intent(); - data.putExtra(EXTRA_TIMESTAMP, result); - getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_OK, data); - } - } -} diff --git a/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.kt b/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.kt new file mode 100644 index 000000000..42881d29f --- /dev/null +++ b/app/src/main/java/org/tasks/dialogs/MyTimePickerDialog.kt @@ -0,0 +1,86 @@ +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 androidx.fragment.app.DialogFragment +import androidx.fragment.app.Fragment +import com.google.android.material.timepicker.MaterialTimePicker +import com.google.android.material.timepicker.TimeFormat.CLOCK_12H +import com.google.android.material.timepicker.TimeFormat.CLOCK_24H +import com.todoroo.andlib.utility.DateUtilities.now +import org.tasks.date.DateTimeUtils.toDateTime +import org.tasks.time.DateTime +import org.tasks.time.DateTimeUtils.startOfDay + +class MyTimePickerDialog : DialogFragment() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val fragment = + (childFragmentManager.findFragmentByTag(FRAG_TAG_TIME_PICKER) as? MaterialTimePicker) + ?: newTimePicker(requireContext(), initial) + .let { + childFragmentManager + .beginTransaction() + .add(it, FRAG_TAG_TIME_PICKER) + .commit() + it + } + with(fragment) { + addOnPositiveButtonClickListener { selected(hour, minute) } + addOnNegativeButtonClickListener { cancel() } + addOnCancelListener { cancel() } + } + } + + private val initial: Long + get() = arguments?.getLong(EXTRA_TIMESTAMP) ?: now().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(target: Fragment, rc: Int, initial: Long) = + MyTimePickerDialog().apply { + arguments = Bundle().apply { + putLong(EXTRA_TIMESTAMP, initial) + } + setTargetFragment(target, rc) + } + + @JvmStatic + fun newTimePicker(context: Context?, initial: Long) = DateTime(initial).let { + MaterialTimePicker.Builder() + .setTimeFormat(if (is24HourFormat(context)) CLOCK_24H else CLOCK_12H) + .setHour(it.hourOfDay) + .setMinute(it.minuteOfHour) + .build() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt b/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt index 5d1e8c9fb..ae290da12 100644 --- a/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt +++ b/app/src/main/java/org/tasks/dialogs/StartDatePicker.kt @@ -17,7 +17,7 @@ import dagger.hilt.android.AndroidEntryPoint import org.tasks.R import org.tasks.databinding.DialogStartDatePickerBinding import org.tasks.date.DateTimeUtils.newDateTime -import org.tasks.dialogs.MyTimePickerDialog.newTimePicker +import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker import org.tasks.locale.Locale import org.tasks.notifications.NotificationManager import org.tasks.time.DateTime diff --git a/app/src/main/java/org/tasks/preferences/fragments/DateAndTime.kt b/app/src/main/java/org/tasks/preferences/fragments/DateAndTime.kt index 3efde67e3..5a47666b1 100644 --- a/app/src/main/java/org/tasks/preferences/fragments/DateAndTime.kt +++ b/app/src/main/java/org/tasks/preferences/fragments/DateAndTime.kt @@ -8,7 +8,7 @@ import androidx.preference.ListPreference import androidx.preference.Preference import dagger.hilt.android.AndroidEntryPoint import org.tasks.R -import org.tasks.dialogs.MyTimePickerDialog.newTimePicker +import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker import org.tasks.injection.InjectingPreferenceFragment import org.tasks.locale.Locale import org.tasks.preferences.Preferences diff --git a/app/src/main/java/org/tasks/preferences/fragments/Notifications.kt b/app/src/main/java/org/tasks/preferences/fragments/Notifications.kt index b4bcc6182..23031eede 100644 --- a/app/src/main/java/org/tasks/preferences/fragments/Notifications.kt +++ b/app/src/main/java/org/tasks/preferences/fragments/Notifications.kt @@ -20,7 +20,7 @@ import kotlinx.coroutines.launch import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.activities.FilterSelectionActivity -import org.tasks.dialogs.MyTimePickerDialog.newTimePicker +import org.tasks.dialogs.MyTimePickerDialog.Companion.newTimePicker import org.tasks.injection.InjectingPreferenceFragment import org.tasks.preferences.DefaultFilterProvider import org.tasks.preferences.Preferences diff --git a/app/src/main/res/color/clock_text_color.xml b/app/src/main/res/color/clock_text_color.xml new file mode 100644 index 000000000..3e706f105 --- /dev/null +++ b/app/src/main/res/color/clock_text_color.xml @@ -0,0 +1,20 @@ + + + + + + diff --git a/app/src/main/res/color/mtrl_choice_chip_background_color.xml b/app/src/main/res/color/mtrl_choice_chip_background_color.xml new file mode 100644 index 000000000..f6de8f232 --- /dev/null +++ b/app/src/main/res/color/mtrl_choice_chip_background_color.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/color/mtrl_choice_chip_text_color.xml b/app/src/main/res/color/mtrl_choice_chip_text_color.xml new file mode 100644 index 000000000..22815ae80 --- /dev/null +++ b/app/src/main/res/color/mtrl_choice_chip_text_color.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/color/mtrl_filled_stroke_color.xml b/app/src/main/res/color/mtrl_filled_stroke_color.xml new file mode 100644 index 000000000..eb178ec72 --- /dev/null +++ b/app/src/main/res/color/mtrl_filled_stroke_color.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/app/src/main/res/color/mtrl_text_btn_text_color_selector.xml b/app/src/main/res/color/mtrl_text_btn_text_color_selector.xml new file mode 100644 index 000000000..8fd80ff08 --- /dev/null +++ b/app/src/main/res/color/mtrl_text_btn_text_color_selector.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index fa0d94db3..368c88499 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -7,8 +7,6 @@ org.tasks org.tasks.opentasks AEdPqrEAAAAI49v5bBusi_bq1bgLBB1LIsepNV0eBrFkQrBZkw - @string/ok - @string/cancel Tasks Shortcut CalDAV EteSync diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 96705e58d..04eb502e3 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -20,6 +20,9 @@ @style/TasksDialogAlert @null @android:style/Animation + @style/ClockTheme + @style/CalendarTheme + @style/OutlinedBox - @@ -211,4 +212,59 @@ fitCenter + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/theme.xml b/app/src/main/res/values/theme.xml index 32c196496..962fcd64e 100644 --- a/app/src/main/res/values/theme.xml +++ b/app/src/main/res/values/theme.xml @@ -21,7 +21,9 @@ @color/text_tertiary 2dp 2 - @bool/is_dark + @style/ClockTheme + @style/CalendarTheme + @style/OutlinedBox