mirror of https://github.com/tasks/tasks
Repurpose "Hide until" as "Start date"
parent
7ac2421957
commit
7f5cbf372a
@ -1,259 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Todoroo Inc
|
||||
*
|
||||
* See the file "LICENSE" for the full license governing this code.
|
||||
*/
|
||||
package com.todoroo.astrid.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.*
|
||||
import android.widget.AdapterView.OnItemSelectedListener
|
||||
import butterknife.BindView
|
||||
import butterknife.OnClick
|
||||
import com.todoroo.andlib.utility.DateUtilities
|
||||
import com.todoroo.astrid.data.Task
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.tasks.R
|
||||
import org.tasks.activities.DateAndTimePickerActivity
|
||||
import org.tasks.date.DateTimeUtils
|
||||
import org.tasks.dialogs.MyTimePickerDialog
|
||||
import org.tasks.locale.Locale
|
||||
import org.tasks.preferences.Preferences
|
||||
import org.tasks.ui.HiddenTopArrayAdapter
|
||||
import org.tasks.ui.TaskEditControlFragment
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Control set for specifying when a task should be hidden
|
||||
*
|
||||
* @author Tim Su <tim></tim>@todoroo.com>
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
class HideUntilControlSet : TaskEditControlFragment(), OnItemSelectedListener {
|
||||
private val spinnerItems: MutableList<HideUntilValue> = ArrayList()
|
||||
|
||||
@Inject lateinit var activity: Activity
|
||||
@Inject lateinit var preferences: Preferences
|
||||
@Inject lateinit var locale: Locale
|
||||
|
||||
@BindView(R.id.hideUntil)
|
||||
lateinit var spinner: Spinner
|
||||
|
||||
@BindView(R.id.clear)
|
||||
lateinit var clearButton: ImageView
|
||||
|
||||
private lateinit var adapter: ArrayAdapter<HideUntilValue>
|
||||
private var previousSetting = Task.HIDE_UNTIL_NONE
|
||||
private var selection = 0
|
||||
private var existingDate = EXISTING_TIME_UNSET
|
||||
|
||||
@OnClick(R.id.clear)
|
||||
fun clearHideUntil() {
|
||||
updateSpinnerOptions(0)
|
||||
selection = 0
|
||||
spinner.setSelection(selection)
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
override fun onRowClick() {
|
||||
spinner.performClick()
|
||||
}
|
||||
|
||||
override fun createView(savedInstanceState: Bundle?) {
|
||||
adapter = object : HiddenTopArrayAdapter<HideUntilValue>(
|
||||
activity, android.R.layout.simple_spinner_item, spinnerItems) {
|
||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||
var selectedItemPosition = position
|
||||
if (parent is AdapterView<*>) {
|
||||
selectedItemPosition = parent.selectedItemPosition
|
||||
}
|
||||
val tv = activity.layoutInflater.inflate(android.R.layout.simple_spinner_item, parent, false) as TextView
|
||||
tv.setPadding(0, 0, 0, 0)
|
||||
val value = getItem(selectedItemPosition)
|
||||
if (value!!.setting == Task.HIDE_UNTIL_NONE) {
|
||||
clearButton.visibility = View.GONE
|
||||
tv.text = value.labelDisplay
|
||||
tv.setTextColor(activity.getColor(R.color.text_tertiary))
|
||||
} else {
|
||||
val display = value.labelDisplay
|
||||
tv.text = getString(R.string.TEA_hideUntil_display, display)
|
||||
tv.setTextColor(activity.getColor(R.color.text_primary))
|
||||
}
|
||||
return tv
|
||||
}
|
||||
}
|
||||
if (savedInstanceState == null) {
|
||||
val dueDate = viewModel.dueDate!!
|
||||
var hideUntil = viewModel.hideUntil!!
|
||||
val dueDay = DateTimeUtils.newDateTime(dueDate)
|
||||
.withHourOfDay(0)
|
||||
.withMinuteOfHour(0)
|
||||
.withSecondOfMinute(0)
|
||||
.withMillisOfSecond(0)
|
||||
|
||||
// For the hide until due case, we need the time component
|
||||
val dueTime = dueDate / 1000L * 1000L
|
||||
if (hideUntil <= 0) {
|
||||
selection = 0
|
||||
hideUntil = 0
|
||||
if (viewModel.isNew) {
|
||||
when (preferences.getIntegerFromString(R.string.p_default_hideUntil_key, Task.HIDE_UNTIL_NONE)) {
|
||||
Task.HIDE_UNTIL_DUE -> selection = 1
|
||||
Task.HIDE_UNTIL_DUE_TIME -> selection = 2
|
||||
Task.HIDE_UNTIL_DAY_BEFORE -> selection = 3
|
||||
Task.HIDE_UNTIL_WEEK_BEFORE -> selection = 4
|
||||
}
|
||||
}
|
||||
} else if (hideUntil == dueDay.millis) {
|
||||
selection = 1
|
||||
hideUntil = 0
|
||||
} else if (hideUntil == dueTime) {
|
||||
selection = 2
|
||||
hideUntil = 0
|
||||
} else if (hideUntil + DateUtilities.ONE_DAY == dueDay.millis) {
|
||||
selection = 3
|
||||
hideUntil = 0
|
||||
} else if (hideUntil + DateUtilities.ONE_WEEK == dueDay.millis) {
|
||||
selection = 4
|
||||
hideUntil = 0
|
||||
}
|
||||
updateSpinnerOptions(hideUntil)
|
||||
} else {
|
||||
updateSpinnerOptions(savedInstanceState.getLong(EXTRA_CUSTOM))
|
||||
selection = savedInstanceState.getInt(EXTRA_SELECTION)
|
||||
}
|
||||
spinner.adapter = adapter
|
||||
spinner.setSelection(selection)
|
||||
spinner.onItemSelectedListener = this
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
override val layout = R.layout.control_set_hide
|
||||
|
||||
override val icon = R.drawable.ic_outline_visibility_off_24px
|
||||
|
||||
override fun controlId() = TAG
|
||||
|
||||
override val isClickable = true
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_HIDE_UNTIL) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
setCustomDate(data!!.getLongExtra(MyTimePickerDialog.EXTRA_TIMESTAMP, 0L))
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(EXTRA_CUSTOM, existingDate)
|
||||
outState.putInt(EXTRA_SELECTION, selection)
|
||||
}
|
||||
|
||||
private fun updateSpinnerOptions(specificDate: Long) {
|
||||
spinnerItems.clear()
|
||||
// set up base values
|
||||
val labelsSpinner = resources.getStringArray(R.array.TEA_hideUntil_spinner)
|
||||
val labelsDisplay = resources.getStringArray(R.array.TEA_hideUntil_display)
|
||||
spinnerItems.addAll(
|
||||
ArrayList(
|
||||
listOf(
|
||||
HideUntilValue(labelsSpinner[0], labelsDisplay[0], Task.HIDE_UNTIL_DUE),
|
||||
HideUntilValue(labelsSpinner[1], labelsDisplay[1], Task.HIDE_UNTIL_DUE_TIME),
|
||||
HideUntilValue(labelsSpinner[2], labelsDisplay[2], Task.HIDE_UNTIL_DAY_BEFORE),
|
||||
HideUntilValue(labelsSpinner[3], labelsDisplay[3], Task.HIDE_UNTIL_WEEK_BEFORE),
|
||||
HideUntilValue(
|
||||
labelsSpinner[4],
|
||||
"",
|
||||
Task.HIDE_UNTIL_SPECIFIC_DAY,
|
||||
-1)))) // no need for a string for display here, since the chosen day will be
|
||||
// displayed
|
||||
existingDate = if (specificDate > 0) {
|
||||
spinnerItems.add(0, getHideUntilValue(specificDate))
|
||||
specificDate
|
||||
} else {
|
||||
spinnerItems.add(
|
||||
0, HideUntilValue(getString(R.string.TEA_hideUntil_label), Task.HIDE_UNTIL_NONE))
|
||||
EXISTING_TIME_UNSET
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
private fun getHideUntilValue(timestamp: Long): HideUntilValue {
|
||||
val hideUntilAsDate = DateTimeUtils.newDateTime(timestamp)
|
||||
return if (hideUntilAsDate.hourOfDay == 0 && hideUntilAsDate.minuteOfHour == 0 && hideUntilAsDate.secondOfMinute == 0) {
|
||||
HideUntilValue(
|
||||
DateUtilities.getDateString(context, DateTimeUtils.newDateTime(timestamp)),
|
||||
Task.HIDE_UNTIL_SPECIFIC_DAY,
|
||||
timestamp)
|
||||
} else {
|
||||
HideUntilValue(
|
||||
DateUtilities.getLongDateStringWithTime(timestamp, locale.locale),
|
||||
Task.HIDE_UNTIL_SPECIFIC_DAY_TIME,
|
||||
timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) {
|
||||
// if specific date selected, show dialog
|
||||
// ... at conclusion of dialog, update our list
|
||||
val item = adapter.getItem(position)
|
||||
if (item!!.date == SPECIFIC_DATE.toLong()) {
|
||||
val customDate = DateTimeUtils.newDateTime(if (existingDate == EXISTING_TIME_UNSET) DateUtilities.now() else existingDate)
|
||||
.withSecondOfMinute(0)
|
||||
val intent = Intent(activity, DateAndTimePickerActivity::class.java)
|
||||
intent.putExtra(DateAndTimePickerActivity.EXTRA_TIMESTAMP, customDate.millis)
|
||||
startActivityForResult(intent, REQUEST_HIDE_UNTIL)
|
||||
spinner.setSelection(previousSetting)
|
||||
} else {
|
||||
previousSetting = position
|
||||
}
|
||||
selection = spinner.selectedItemPosition
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
// --- listening for events
|
||||
private fun setCustomDate(timestamp: Long) {
|
||||
updateSpinnerOptions(timestamp)
|
||||
spinner.setSelection(0)
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
override fun onNothingSelected(arg0: AdapterView<*>?) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
private fun refreshDisplayView() {
|
||||
viewModel.hideUntilValue = adapter.getItem(selection)
|
||||
clearButton.visibility = if (viewModel.hideUntilValue!!.setting == Task.HIDE_UNTIL_NONE) View.GONE else View.VISIBLE
|
||||
}
|
||||
|
||||
class HideUntilValue internal constructor(
|
||||
private val labelSpinner: String,
|
||||
val labelDisplay: String,
|
||||
val setting: Int,
|
||||
val date: Long = 0
|
||||
) {
|
||||
internal constructor(label: String, setting: Int) : this(label, label, setting, 0)
|
||||
|
||||
internal constructor(label: String, setting: Int, date: Long) : this(label, label, setting, date)
|
||||
|
||||
override fun toString() = labelSpinner
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = R.string.TEA_ctrl_hide_until_pref
|
||||
private const val EXTRA_CUSTOM = "extra_custom"
|
||||
private const val EXTRA_SELECTION = "extra_selection"
|
||||
private const val SPECIFIC_DATE = -1
|
||||
private const val EXISTING_TIME_UNSET = -2L
|
||||
private const val REQUEST_HIDE_UNTIL = 11011
|
||||
}
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
package com.todoroo.astrid.ui
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.TextView
|
||||
import butterknife.BindView
|
||||
import com.todoroo.andlib.utility.DateUtilities
|
||||
import com.todoroo.andlib.utility.DateUtilities.now
|
||||
import com.todoroo.astrid.data.Task
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.tasks.R
|
||||
import org.tasks.date.DateTimeUtils.newDateTime
|
||||
import org.tasks.date.DateTimeUtils.toDateTime
|
||||
import org.tasks.dialogs.StartDatePicker
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.DAY_BEFORE_DUE
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.DUE_DATE
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.DUE_TIME
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.EXTRA_DAY
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.EXTRA_TIME
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.NO_DAY
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.NO_TIME
|
||||
import org.tasks.dialogs.StartDatePicker.Companion.WEEK_BEFORE_DUE
|
||||
import org.tasks.locale.Locale
|
||||
import org.tasks.preferences.Preferences
|
||||
import org.tasks.time.DateTimeUtils.millisOfDay
|
||||
import org.tasks.time.DateTimeUtils.startOfDay
|
||||
import org.tasks.ui.TaskEditControlFragment
|
||||
import java.time.format.FormatStyle
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class StartDateControlSet : TaskEditControlFragment() {
|
||||
@Inject lateinit var activity: Activity
|
||||
@Inject lateinit var preferences: Preferences
|
||||
@Inject lateinit var locale: Locale
|
||||
|
||||
@BindView(R.id.start_date)
|
||||
lateinit var startDate: TextView
|
||||
|
||||
private val dueDateTime
|
||||
get() = viewModel.dueDate!!
|
||||
|
||||
private var selectedDay = NO_DAY
|
||||
private var selectedTime = NO_TIME
|
||||
|
||||
override fun onRowClick() {
|
||||
val fragmentManager = parentFragmentManager
|
||||
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
|
||||
StartDatePicker.newDateTimePicker(
|
||||
this,
|
||||
REQUEST_HIDE_UNTIL,
|
||||
selectedDay,
|
||||
selectedTime,
|
||||
preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false))
|
||||
.show(fragmentManager, FRAG_TAG_DATE_PICKER)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createView(savedInstanceState: Bundle?) {
|
||||
if (savedInstanceState == null) {
|
||||
val dueDay = dueDateTime.startOfDay()
|
||||
val dueTime = dueDateTime.millisOfDay()
|
||||
val hideUntil = viewModel.hideUntil?.takeIf { it > 0 }?.toDateTime()
|
||||
if (hideUntil == null) {
|
||||
if (viewModel.isNew) {
|
||||
when (preferences.getIntegerFromString(R.string.p_default_hideUntil_key, Task.HIDE_UNTIL_NONE)) {
|
||||
Task.HIDE_UNTIL_DUE -> selectedDay = DUE_DATE
|
||||
Task.HIDE_UNTIL_DUE_TIME -> selectedDay = DUE_TIME
|
||||
Task.HIDE_UNTIL_DAY_BEFORE -> selectedDay = DAY_BEFORE_DUE
|
||||
Task.HIDE_UNTIL_WEEK_BEFORE -> selectedDay = WEEK_BEFORE_DUE
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selectedDay = hideUntil.startOfDay().millis
|
||||
selectedTime = hideUntil.millisOfDay
|
||||
selectedDay = when (selectedDay) {
|
||||
dueDay -> if (selectedTime == dueTime) {
|
||||
selectedTime = NO_TIME
|
||||
DUE_TIME
|
||||
} else {
|
||||
DUE_DATE
|
||||
}
|
||||
dueDay.toDateTime().minusDays(1).millis ->
|
||||
DAY_BEFORE_DUE
|
||||
dueDay.toDateTime().minusDays(7).millis ->
|
||||
WEEK_BEFORE_DUE
|
||||
else -> selectedDay
|
||||
}
|
||||
}
|
||||
} else {
|
||||
selectedDay = savedInstanceState.getLong(EXTRA_DAY)
|
||||
selectedTime = savedInstanceState.getInt(EXTRA_TIME)
|
||||
}
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
override val layout = R.layout.control_set_hide
|
||||
|
||||
override val icon = R.drawable.ic_pending_actions_24px
|
||||
|
||||
override fun controlId() = TAG
|
||||
|
||||
override val isClickable = true
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_HIDE_UNTIL) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
selectedDay = data?.getLongExtra(EXTRA_DAY, 0L) ?: NO_DAY
|
||||
selectedTime = data?.getIntExtra(EXTRA_TIME, 0) ?: NO_TIME
|
||||
applySelectionToHideUntil()
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLong(EXTRA_DAY, selectedDay)
|
||||
outState.putInt(EXTRA_TIME, selectedTime)
|
||||
}
|
||||
|
||||
private fun getRelativeDateString(resId: Int) = if (selectedTime == NO_TIME) {
|
||||
getString(resId)
|
||||
} else {
|
||||
"${getString(resId)} ${DateUtilities.getTimeString(context, newDateTime().withMillisOfDay(selectedTime))}"
|
||||
}
|
||||
|
||||
private fun refreshDisplayView() {
|
||||
startDate.text = when (selectedDay) {
|
||||
DUE_DATE -> getRelativeDateString(R.string.due_date)
|
||||
DUE_TIME -> getString(R.string.due_time)
|
||||
DAY_BEFORE_DUE -> getRelativeDateString(R.string.day_before_due)
|
||||
WEEK_BEFORE_DUE -> getRelativeDateString(R.string.week_before_due)
|
||||
in 1..Long.MAX_VALUE -> DateUtilities.getRelativeDateTime(
|
||||
activity,
|
||||
selectedDay + selectedTime,
|
||||
locale.locale,
|
||||
FormatStyle.FULL,
|
||||
preferences.alwaysDisplayFullDate,
|
||||
false
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
val started = viewModel.hideUntil?.takeIf { it > 0 }?.let { it < now() } ?: false
|
||||
startDate.setTextColor(
|
||||
activity.getColor(if (started) R.color.overdue else R.color.text_primary)
|
||||
)
|
||||
}
|
||||
|
||||
fun onDueDateChanged() = applySelectionToHideUntil()
|
||||
|
||||
private fun applySelectionToHideUntil() {
|
||||
val due = dueDateTime.takeIf { it > 0 }?.toDateTime()
|
||||
val millisOfDay = selectedTime
|
||||
viewModel.hideUntil = when (selectedDay) {
|
||||
DUE_DATE -> due?.withMillisOfDay(millisOfDay)?.millis ?: 0
|
||||
DUE_TIME -> due?.millis ?: 0
|
||||
DAY_BEFORE_DUE -> due?.minusDays(1)?.withMillisOfDay(millisOfDay)?.millis ?: 0
|
||||
WEEK_BEFORE_DUE -> due?.minusDays(7)?.withMillisOfDay(millisOfDay)?.millis ?: 0
|
||||
else -> selectedDay + selectedTime
|
||||
}
|
||||
refreshDisplayView()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = R.string.TEA_ctrl_hide_until_pref
|
||||
private const val REQUEST_HIDE_UNTIL = 11011
|
||||
private const val FRAG_TAG_DATE_PICKER = "frag_tag_date_picker"
|
||||
}
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
package org.tasks.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import butterknife.ButterKnife
|
||||
import butterknife.OnClick
|
||||
import com.todoroo.andlib.utility.DateUtilities
|
||||
import com.todoroo.astrid.dao.TaskDao
|
||||
import com.todoroo.astrid.data.Task
|
||||
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.locale.Locale
|
||||
import org.tasks.notifications.NotificationManager
|
||||
import org.tasks.time.DateTime
|
||||
import java.time.format.FormatStyle
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class StartDatePicker : BaseDateTimePicker() {
|
||||
|
||||
@Inject lateinit var activity: Activity
|
||||
@Inject lateinit var locale: Locale
|
||||
@Inject lateinit var taskDao: TaskDao
|
||||
@Inject lateinit var notificationManager: NotificationManager
|
||||
|
||||
lateinit var binding: DialogStartDatePickerBinding
|
||||
private var customDate = NO_DAY
|
||||
private var customTime = NO_TIME
|
||||
private var selectedDay = NO_DAY
|
||||
private var selectedTime = NO_TIME
|
||||
private val today = newDateTime().startOfDay()
|
||||
override val calendarView get() = binding.calendarView
|
||||
override val morningButton get() = binding.shortcuts.morningButton
|
||||
override val afternoonButton get() = binding.shortcuts.afternoonButton
|
||||
override val eveningButton get() = binding.shortcuts.eveningButton
|
||||
override val nightButton get() = binding.shortcuts.nightButton
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_TIME = 10101
|
||||
private const val FRAG_TAG_TIME_PICKER = "frag_tag_time_picker"
|
||||
const val EXTRA_DAY = "extra_day"
|
||||
const val EXTRA_TIME = "extra_time"
|
||||
const val NO_DAY = 0L
|
||||
const val NO_TIME = 0
|
||||
const val DUE_DATE = -1L
|
||||
const val DAY_BEFORE_DUE = -2L
|
||||
const val WEEK_BEFORE_DUE = -3L
|
||||
const val DUE_TIME = -4L
|
||||
|
||||
fun newDateTimePicker(target: Fragment, rc: Int, day: Long, time: Int, autoClose: Boolean): StartDatePicker {
|
||||
val bundle = Bundle()
|
||||
bundle.putLong(EXTRA_DAY, day)
|
||||
bundle.putInt(EXTRA_TIME, time)
|
||||
bundle.putBoolean(EXTRA_AUTO_CLOSE, autoClose)
|
||||
val fragment = StartDatePicker()
|
||||
fragment.arguments = bundle
|
||||
fragment.setTargetFragment(target, rc)
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
binding = DialogStartDatePickerBinding.inflate(theme.getLayoutInflater(context))
|
||||
setupShortcutsAndCalendar()
|
||||
ButterKnife.bind(this, binding.root)
|
||||
binding.calendarView.setOnDateChangeListener { _, y, m, d ->
|
||||
returnDate(day = DateTime(y, m + 1, d).millis)
|
||||
refreshButtons()
|
||||
}
|
||||
selectedDay = savedInstanceState?.getLong(EXTRA_DAY) ?: requireArguments().getLong(EXTRA_DAY)
|
||||
selectedTime =
|
||||
savedInstanceState?.getInt(EXTRA_TIME)
|
||||
?: requireArguments().getInt(EXTRA_TIME)
|
||||
.takeIf { Task.hasDueTime(it.toLong()) }
|
||||
?: NO_TIME
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun refreshButtons() {
|
||||
when (selectedDay) {
|
||||
0L -> binding.shortcuts.dateGroup.check(R.id.no_date_button)
|
||||
DUE_DATE -> binding.shortcuts.dateGroup.check(R.id.due_date_button)
|
||||
DUE_TIME -> {
|
||||
binding.shortcuts.dateGroup.check(R.id.due_time_button)
|
||||
binding.shortcuts.timeGroup.clearChecked()
|
||||
}
|
||||
DAY_BEFORE_DUE -> binding.shortcuts.dateGroup.check(R.id.day_before_due_button)
|
||||
WEEK_BEFORE_DUE -> binding.shortcuts.dateGroup.check(R.id.week_before_due_button)
|
||||
else -> {
|
||||
customDate = selectedDay
|
||||
binding.shortcuts.dateGroup.check(R.id.current_date_selection)
|
||||
binding.shortcuts.currentDateSelection.visibility = View.VISIBLE
|
||||
binding.shortcuts.currentDateSelection.text =
|
||||
DateUtilities.getRelativeDay(context, selectedDay, locale.locale, FormatStyle.MEDIUM)
|
||||
}
|
||||
}
|
||||
if (Task.hasDueTime(selectedTime.toLong())) {
|
||||
when (selectedTime) {
|
||||
morning -> binding.shortcuts.timeGroup.check(R.id.morning_button)
|
||||
afternoon -> binding.shortcuts.timeGroup.check(R.id.afternoon_button)
|
||||
evening -> binding.shortcuts.timeGroup.check(R.id.evening_button)
|
||||
night -> binding.shortcuts.timeGroup.check(R.id.night_button)
|
||||
else -> {
|
||||
customTime = selectedTime
|
||||
binding.shortcuts.timeGroup.check(R.id.current_time_selection)
|
||||
binding.shortcuts.currentTimeSelection.visibility = View.VISIBLE
|
||||
binding.shortcuts.currentTimeSelection.text = DateUtilities.getTimeString(context, today.withMillisOfDay(selectedTime))
|
||||
}
|
||||
}
|
||||
if (selectedDay == DUE_TIME) {
|
||||
selectedDay = DUE_DATE
|
||||
}
|
||||
} else if (selectedDay != DUE_TIME) {
|
||||
binding.shortcuts.timeGroup.check(R.id.no_time)
|
||||
}
|
||||
if (selectedDay > 0) {
|
||||
binding.calendarView.setDate(selectedDay, true, true)
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.no_date_button)
|
||||
fun clearDate() = returnDate(day = 0, time = 0)
|
||||
|
||||
@OnClick(R.id.no_time)
|
||||
fun clearTime() = returnDate(
|
||||
day = when (selectedDay) {
|
||||
DUE_TIME -> DUE_DATE
|
||||
else -> selectedDay
|
||||
},
|
||||
time = 0
|
||||
)
|
||||
|
||||
@OnClick(R.id.due_date_button)
|
||||
fun setToday() = returnDate(day = DUE_DATE)
|
||||
|
||||
@OnClick(R.id.day_before_due_button)
|
||||
fun setTomorrow() = returnDate(day = DAY_BEFORE_DUE)
|
||||
|
||||
@OnClick(R.id.week_before_due_button)
|
||||
fun setNextWeek() = returnDate(day = WEEK_BEFORE_DUE)
|
||||
|
||||
@OnClick(R.id.morning_button)
|
||||
fun setMorning() = returnSelectedTime(morning)
|
||||
|
||||
@OnClick(R.id.afternoon_button)
|
||||
fun setAfternoon() = returnSelectedTime(afternoon)
|
||||
|
||||
@OnClick(R.id.evening_button)
|
||||
fun setEvening() = returnSelectedTime(evening)
|
||||
|
||||
@OnClick(R.id.night_button)
|
||||
fun setNight() = returnSelectedTime(night)
|
||||
|
||||
@OnClick(R.id.due_time_button)
|
||||
fun setDueTime() = returnDate(day = DUE_TIME, time = NO_TIME)
|
||||
|
||||
@OnClick(R.id.current_date_selection)
|
||||
fun currentDate() = returnDate(day = customDate)
|
||||
|
||||
@OnClick(R.id.current_time_selection)
|
||||
fun currentTime() = returnSelectedTime(customTime)
|
||||
|
||||
@OnClick(R.id.pick_time_button)
|
||||
fun pickTime() {
|
||||
val time = if (selectedTime < 0 || !Task.hasDueTime(today.withMillisOfDay(selectedTime).millis)) {
|
||||
today.noon().millisOfDay
|
||||
} else {
|
||||
selectedTime
|
||||
}
|
||||
newTimePicker(this, REQUEST_TIME, today.withMillisOfDay(time).millis)
|
||||
.show(parentFragmentManager, FRAG_TAG_TIME_PICKER)
|
||||
}
|
||||
|
||||
private fun returnSelectedTime(millisOfDay: Int) {
|
||||
val day = when {
|
||||
selectedDay == DUE_TIME -> DUE_DATE
|
||||
selectedDay != 0L -> selectedDay
|
||||
today.withMillisOfDay(millisOfDay).isAfterNow -> today.millis
|
||||
else -> today.plusDays(1).millis
|
||||
}
|
||||
returnDate(day = day, time = millisOfDay)
|
||||
}
|
||||
|
||||
private fun returnDate(day: Long = selectedDay, time: Int = selectedTime) {
|
||||
selectedDay = day
|
||||
selectedTime = time
|
||||
if (closeAutomatically()) {
|
||||
sendSelected()
|
||||
} else {
|
||||
refreshButtons()
|
||||
}
|
||||
}
|
||||
|
||||
override fun sendSelected() {
|
||||
if (selectedDay != arguments?.getLong(EXTRA_DAY)
|
||||
|| selectedTime != arguments?.getInt(EXTRA_TIME)) {
|
||||
val intent = Intent().apply {
|
||||
putExtra(EXTRA_DAY, selectedDay)
|
||||
putExtra(EXTRA_TIME, selectedTime)
|
||||
}
|
||||
targetFragment?.onActivityResult(targetRequestCode, RESULT_OK, intent)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
||||
outState.putLong(EXTRA_DAY, selectedDay)
|
||||
outState.putInt(EXTRA_TIME, selectedTime)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_TIME) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
val timestamp = data!!.getLongExtra(MyTimePickerDialog.EXTRA_TIMESTAMP, today.millis)
|
||||
returnSelectedTime(newDateTime(timestamp).millisOfDay + 1000)
|
||||
} else {
|
||||
refreshButtons()
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/start_date"
|
||||
style="@style/TaskEditTextPrimary"
|
||||
android:hint="@string/no_start_date"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="100"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/hideUntil"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/control_set_clear_button"/>
|
||||
|
||||
</LinearLayout>
|
||||
android:textAlignment="viewStart" />
|
||||
|
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
|
||||
android:background="@color/dialog_background">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="@dimen/keyline_first">
|
||||
|
||||
<include
|
||||
layout="@layout/start_date_picker_shortcuts"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/shortcuts" />
|
||||
|
||||
<CalendarView
|
||||
android:id="@+id/calendar_view"
|
||||
android:layout_below="@id/shortcuts"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/date_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/half_keyline_first"
|
||||
android:layout_marginBottom="@dimen/half_keyline_first"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/guideline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_max="wrap"
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
app:singleSelection="true"
|
||||
android:layout_marginStart="16dp">
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/current_date_selection"
|
||||
style="@style/DateTimeShortcuts"
|
||||
tools:text="Nov 24, 2021"
|
||||
android:visibility="gone"
|
||||
app:icon="@drawable/ic_outline_today_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/due_date_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:text="@string/due_date"
|
||||
app:icon="@drawable/ic_calendar_today_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/due_time_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
app:icon="@drawable/ic_outline_schedule_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:text="@string/due_time" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/day_before_due_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:text="@string/day_before_due"
|
||||
app:icon="@drawable/ic_outline_wb_sunny_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/due_date_button" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/week_before_due_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
app:icon="@drawable/ic_date_range_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/day_before_due_button"
|
||||
android:text="@string/week_before_due" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/no_date_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:text="@string/no_date"
|
||||
app:icon="@drawable/ic_outline_not_interested_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/week_before_due_button" />
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.5" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/time_group"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/half_keyline_first"
|
||||
android:layout_marginBottom="@dimen/half_keyline_first"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintLeft_toRightOf="@id/guideline"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_max="wrap"
|
||||
app:layout_constraintWidth_percent="0.5"
|
||||
app:selectionRequired="true"
|
||||
app:singleSelection="true"
|
||||
android:layout_marginEnd="16dp">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/current_time_selection"
|
||||
style="@style/DateTimeShortcuts"
|
||||
app:icon="@drawable/ic_outline_schedule_24px"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible"
|
||||
tools:text="08:15" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/morning_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
tools:text="9 AM"
|
||||
app:icon="@drawable/ic_local_cafe_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/afternoon_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:layout_marginTop="1dp"
|
||||
tools:text="1 PM"
|
||||
app:icon="@drawable/ic_outline_wb_sunny_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/evening_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
tools:text="5 PM"
|
||||
app:icon="@drawable/ic_weather_sunset"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/night_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
tools:text="8 PM"
|
||||
app:icon="@drawable/ic_nights_stay_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/pick_time_button"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:text="@string/shortcut_pick_time"
|
||||
app:icon="@drawable/ic_outline_schedule_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/no_time"
|
||||
style="@style/DateTimeShortcuts"
|
||||
android:text="@string/no_time"
|
||||
app:icon="@drawable/ic_outline_not_interested_24px"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue