Skip to content

Commit 866957b

Browse files
committed
Split dateformat into date and time and overnote and note view
1 parent e4195ff commit 866957b

29 files changed

Lines changed: 318 additions & 130 deletions

File tree

app/src/main/java/com/philkes/notallyx/presentation/UiExtensions.kt

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ import com.philkes.notallyx.presentation.view.note.listitem.ListManager
110110
import com.philkes.notallyx.presentation.view.note.listitem.adapter.ListItemVH
111111
import com.philkes.notallyx.presentation.viewmodel.BaseNoteModel
112112
import com.philkes.notallyx.presentation.viewmodel.preference.DateFormat
113+
import com.philkes.notallyx.presentation.viewmodel.preference.TimeFormat
113114
import com.philkes.notallyx.presentation.viewmodel.preference.displayBodySize
114115
import com.philkes.notallyx.utils.changehistory.ChangeHistory
115116
import com.philkes.notallyx.utils.changehistory.EditTextState
@@ -290,12 +291,14 @@ fun ViewGroup.addIconButton(
290291
fun TextView.displayFormattedTimestamp(
291292
timestamp: Long?,
292293
dateFormat: DateFormat,
294+
timeFormat: TimeFormat,
293295
prefixResId: Int? = null,
294296
) {
295-
if (dateFormat != DateFormat.NONE && timestamp != null) {
297+
if ((dateFormat != DateFormat.NONE || timeFormat != TimeFormat.NONE) && timestamp != null) {
296298
visibility = View.VISIBLE
297299
text =
298-
"${prefixResId?.let { getString(it) } ?: ""} ${formatTimestamp(timestamp, dateFormat)}"
300+
"${prefixResId?.let { getString(it) } ?: ""} ${Date(timestamp).format(dateFormat, timeFormat)}"
301+
.trim()
299302
} else visibility = View.GONE
300303
}
301304

@@ -456,6 +459,17 @@ fun <T, C> NotNullLiveData<T>.merge(liveData: NotNullLiveData<C>): MediatorLiveD
456459
}
457460
}
458461

462+
fun <T, C, B> NotNullLiveData<T>.merge(
463+
liveData: NotNullLiveData<C>,
464+
liveData2: NotNullLiveData<B>,
465+
): MediatorLiveData<Triple<T, C, B>> {
466+
return MediatorLiveData<Triple<T, C, B>>().apply {
467+
addSource(this@merge) { value1 -> value = Triple(value1, liveData.value, liveData2.value) }
468+
addSource(liveData) { value2 -> value = Triple(this@merge.value, value2, liveData2.value) }
469+
addSource(liveData2) { value3 -> value = Triple(this@merge.value, liveData.value, value3) }
470+
}
471+
}
472+
459473
fun <T, C> NotNullLiveData<T>.merge(liveData: LiveData<C>): MediatorLiveData<Pair<T, C?>> {
460474
return MediatorLiveData<Pair<T, C?>>().apply {
461475
addSource(this@merge) { value1 -> value = Pair(value1, liveData.value) }
@@ -617,24 +631,41 @@ private fun formatTimestamp(timestamp: Long, dateFormat: DateFormat): String {
617631
}
618632

619633
private val ISO_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US)
620-
621-
fun Date.format(dateFormat: DateFormat = DateFormat.TIMESTAMP_SHORT): String {
622-
return when (dateFormat) {
623-
DateFormat.NONE -> ""
624-
DateFormat.RELATIVE -> PrettyTime().format(this)
625-
DateFormat.ABSOLUTE ->
626-
java.text.DateFormat.getDateInstance(java.text.DateFormat.FULL).format(this)
627-
DateFormat.ABSOLUTE_SHORT ->
628-
java.text.DateFormat.getDateInstance(java.text.DateFormat.SHORT).format(this)
629-
DateFormat.SHORT_ISO -> {
630-
ISO_DATE_FORMAT.format(this)
634+
private val MM_DD_YY_FORMAT = SimpleDateFormat("MM/dd/yy", Locale.US)
635+
private val DD_MM_YY_FORMAT = SimpleDateFormat("dd.MM.yy", Locale.GERMANY)
636+
private val TWENTY_FOUR_H_FORMAT = SimpleDateFormat("HH:mm", Locale.GERMANY)
637+
private val AM_PM_FORMAT = SimpleDateFormat("hh:mm a", Locale.US)
638+
639+
fun Date.format(
640+
dateFormat: DateFormat = DateFormat.DD_MM_YY,
641+
timeFormat: TimeFormat = TimeFormat.TWENTY_FOUR_H,
642+
): String {
643+
if (dateFormat == DateFormat.NONE && timeFormat == TimeFormat.NONE) {
644+
return ""
645+
}
646+
val datePart =
647+
when (dateFormat) {
648+
DateFormat.NONE -> ""
649+
DateFormat.RELATIVE -> PrettyTime().format(this)
650+
DateFormat.ABSOLUTE ->
651+
java.text.DateFormat.getDateInstance(java.text.DateFormat.FULL).format(this)
652+
DateFormat.SHORT_ISO -> {
653+
ISO_DATE_FORMAT.format(this)
654+
}
655+
DateFormat.MM_DD_YY -> MM_DD_YY_FORMAT.format(this)
656+
DateFormat.DD_MM_YY -> DD_MM_YY_FORMAT.format(this)
631657
}
632-
DateFormat.TIMESTAMP_SHORT ->
633-
java.text.DateFormat.getDateTimeInstance(
634-
java.text.DateFormat.SHORT,
635-
java.text.DateFormat.SHORT,
636-
)
637-
.format(this)
658+
val timePart =
659+
when (timeFormat) {
660+
TimeFormat.NONE -> ""
661+
TimeFormat.TWENTY_FOUR_H -> TWENTY_FOUR_H_FORMAT.format(this)
662+
TimeFormat.AM_PM -> AM_PM_FORMAT.format(this)
663+
}
664+
665+
return if (datePart.isNotEmpty() && timePart.isNotEmpty()) {
666+
"$datePart $timePart"
667+
} else {
668+
datePart + timePart
638669
}
639670
}
640671

@@ -1142,7 +1173,12 @@ fun Context.createTextView(textResId: Int, padding: Int = 16.dp): TextView {
11421173
}
11431174
}
11441175

1145-
fun Chip.setupReminderChip(baseNote: BaseNote, textSize: Float? = null) {
1176+
fun Chip.setupReminderChip(
1177+
baseNote: BaseNote,
1178+
dateFormat: DateFormat,
1179+
timeFormat: TimeFormat,
1180+
textSize: Float? = null,
1181+
) {
11461182
val now = Date(System.currentTimeMillis())
11471183
val mostRecentNotificationDate =
11481184
baseNote.reminders.findNextNotificationDate()
@@ -1153,7 +1189,7 @@ fun Chip.setupReminderChip(baseNote: BaseNote, textSize: Float? = null) {
11531189
}
11541190
this.apply {
11551191
visibility = VISIBLE
1156-
text = mostRecentNotificationDate.format()
1192+
text = mostRecentNotificationDate.format(dateFormat, timeFormat)
11571193
textSize?.let {
11581194
setTextSizeSp(it)
11591195
chipIconSize =

app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/NotallyFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ abstract class NotallyFragment : Fragment(), ItemListener {
262262
with(model.preferences) {
263263
BaseNoteAdapter(
264264
model.actionMode.selectedIds,
265-
dateFormat.value,
265+
dateFormatOverview.value,
266+
timeFormatOverview.value,
266267
notesAdapterSortCallback(),
267268
BaseNoteVHPreferences(
268269
textSizeOverview.value,

app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt

Lines changed: 66 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.google.android.material.slider.Slider
1515
import com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE
1616
import com.philkes.notallyx.R
1717
import com.philkes.notallyx.databinding.ChoiceItemBinding
18+
import com.philkes.notallyx.databinding.DialogDatetimeFormatBinding
1819
import com.philkes.notallyx.databinding.DialogNotesSortBinding
1920
import com.philkes.notallyx.databinding.DialogPreferenceBooleanBinding
2021
import com.philkes.notallyx.databinding.DialogPreferenceEnumWithToggleBinding
@@ -47,6 +48,7 @@ import com.philkes.notallyx.presentation.viewmodel.preference.SortDirection
4748
import com.philkes.notallyx.presentation.viewmodel.preference.StringPreference
4849
import com.philkes.notallyx.presentation.viewmodel.preference.TextProvider
4950
import com.philkes.notallyx.presentation.viewmodel.preference.Theme
51+
import com.philkes.notallyx.presentation.viewmodel.preference.TimeFormat
5052
import com.philkes.notallyx.utils.canAuthenticateWithBiometrics
5153
import com.philkes.notallyx.utils.toReadablePath
5254

@@ -191,55 +193,6 @@ fun PreferenceBinding.setup(
191193
}
192194
}
193195

194-
fun PreferenceBinding.setup(
195-
dateFormatPreference: EnumPreference<DateFormat>,
196-
dateFormatValue: DateFormat,
197-
applyToNoteViewValue: Boolean,
198-
context: Context,
199-
layoutInflater: LayoutInflater,
200-
onSave: (dateFormat: DateFormat, applyToEditMode: Boolean) -> Unit,
201-
) {
202-
Title.setText(dateFormatPreference.titleResId!!)
203-
204-
Value.text = dateFormatValue.getText(context)
205-
206-
root.setOnClickListener {
207-
val layout = DialogPreferenceEnumWithToggleBinding.inflate(layoutInflater, null, false)
208-
layout.EnumHint.apply {
209-
setText(R.string.date_format_hint)
210-
isVisible = true
211-
}
212-
DateFormat.entries.forEachIndexed { idx, dateFormat ->
213-
ChoiceItemBinding.inflate(layoutInflater).root.apply {
214-
id = idx
215-
text = dateFormat.getText(context)
216-
tag = dateFormat
217-
layout.EnumRadioGroup.addView(this)
218-
if (dateFormat == dateFormatValue) {
219-
layout.EnumRadioGroup.check(this.id)
220-
}
221-
}
222-
}
223-
224-
layout.Toggle.apply {
225-
setText(R.string.date_format_apply_in_note_view)
226-
isChecked = applyToNoteViewValue
227-
}
228-
229-
MaterialAlertDialogBuilder(context)
230-
.setTitle(dateFormatPreference.titleResId)
231-
.setView(layout.root)
232-
.setPositiveButton(R.string.save) { dialog, _ ->
233-
dialog.cancel()
234-
val dateFormat = layout.EnumRadioGroup.checkedTag() as DateFormat
235-
val applyToNoteView = layout.Toggle.isChecked
236-
onSave(dateFormat, applyToNoteView)
237-
}
238-
.setCancelButton()
239-
.show()
240-
}
241-
}
242-
243196
fun PreferenceBinding.setup(
244197
themePreference: EnumPreference<Theme>,
245198
themeValue: Theme,
@@ -634,3 +587,67 @@ fun PreferenceBinding.setupStartView(
634587
.showAndFocus(allowFullSize = true)
635588
}
636589
}
590+
591+
fun PreferenceBinding.setupDateTimeFormat(
592+
titleResId: Int,
593+
datePreference: EnumPreference<DateFormat>,
594+
timePreference: EnumPreference<TimeFormat>,
595+
context: Context,
596+
layoutInflater: LayoutInflater,
597+
onSave: (dateFormat: DateFormat, timeFormat: TimeFormat) -> Unit,
598+
) {
599+
Title.setText(titleResId)
600+
val updateValueText = {
601+
val dateText =
602+
if (datePreference.value == DateFormat.NONE) ""
603+
else datePreference.value.getText(context)
604+
val timeText =
605+
if (timePreference.value == TimeFormat.NONE) ""
606+
else timePreference.value.getText(context)
607+
Value.text =
608+
when {
609+
datePreference.value == DateFormat.NONE &&
610+
timePreference.value == TimeFormat.NONE ->
611+
datePreference.value.getText(context) // Shows "None"
612+
datePreference.value == DateFormat.NONE -> timeText
613+
timePreference.value == TimeFormat.NONE -> dateText
614+
else -> "$dateText $timeText"
615+
}
616+
}
617+
updateValueText()
618+
619+
root.setOnClickListener {
620+
val layout = DialogDatetimeFormatBinding.inflate(layoutInflater, null, false)
621+
var selectedDate = datePreference.value
622+
var selectedTime = timePreference.value
623+
624+
val dateEntries = DateFormat.entries.map { it.getText(context) }.toTypedArray()
625+
layout.DateSelectionBox.apply {
626+
setSimpleItems(dateEntries)
627+
select(selectedDate.getText(context))
628+
setOnItemClickListener { _, _, position, _ ->
629+
selectedDate = DateFormat.entries[position]
630+
}
631+
}
632+
633+
val timeEntries = TimeFormat.entries.map { it.getText(context) }.toTypedArray()
634+
layout.TimeSelectionBox.apply {
635+
setSimpleItems(timeEntries)
636+
select(selectedTime.getText(context))
637+
setOnItemClickListener { _, _, position, _ ->
638+
selectedTime = TimeFormat.entries[position]
639+
}
640+
}
641+
642+
MaterialAlertDialogBuilder(context)
643+
.setTitle(titleResId)
644+
.setView(layout.root)
645+
.setPositiveButton(R.string.save) { dialog, _ ->
646+
dialog.cancel()
647+
onSave(selectedDate, selectedTime)
648+
updateValueText()
649+
}
650+
.setCancelButton()
651+
.showAndFocus(allowFullSize = true)
652+
}
653+
}

app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -293,17 +293,29 @@ class SettingsFragment : Fragment() {
293293
}
294294
}
295295

296-
dateFormat.merge(applyDateFormatInNoteView).observe(viewLifecycleOwner) {
297-
(dateFormatValue, applyDateFormatInEditNoteValue) ->
298-
binding.DateFormat.setup(
299-
dateFormat,
300-
dateFormatValue,
301-
applyDateFormatInEditNoteValue,
296+
dateFormatOverview.merge(timeFormatOverview).observe(viewLifecycleOwner) { (date, time) ->
297+
binding.DateFormatOverview.setupDateTimeFormat(
298+
R.string.date_format_overview,
299+
dateFormatOverview,
300+
timeFormatOverview,
302301
requireContext(),
303302
layoutInflater,
304-
) { newDateFormatValue, newApplyDateFormatInEditNote ->
305-
model.savePreference(dateFormat, newDateFormatValue)
306-
model.savePreference(applyDateFormatInNoteView, newApplyDateFormatInEditNote)
303+
) { newDate, newTime ->
304+
model.savePreference(dateFormatOverview, newDate)
305+
model.savePreference(timeFormatOverview, newTime)
306+
}
307+
}
308+
309+
dateFormatNoteView.merge(timeFormatNoteView).observe(viewLifecycleOwner) { (date, time) ->
310+
binding.DateFormatNoteView.setupDateTimeFormat(
311+
R.string.date_format_note_view,
312+
dateFormatNoteView,
313+
timeFormatNoteView,
314+
requireContext(),
315+
layoutInflater,
316+
) { newDate, newTime ->
317+
model.savePreference(dateFormatNoteView, newDate)
318+
model.savePreference(timeFormatNoteView, newTime)
307319
}
308320
}
309321

@@ -618,15 +630,24 @@ class SettingsFragment : Fragment() {
618630
model.savePreference(preference, preference.value.copy(periodInDays = 0))
619631
}
620632
}
621-
lastExecutionPreference.observe(viewLifecycleOwner) { time ->
622-
binding.PeriodicBackupLastExecution.apply {
623-
if (time != -1L) {
624-
isVisible = true
625-
text =
626-
"${requireContext().getString(R.string.auto_backup_last)}: ${Date(time).format()}"
627-
} else isVisible = false
633+
lastExecutionPreference
634+
.merge(model.preferences.dateFormatOverview, model.preferences.timeFormatOverview)
635+
.observe(viewLifecycleOwner) { (time, _, _) ->
636+
binding.PeriodicBackupLastExecution.apply {
637+
if (time != -1L) {
638+
isVisible = true
639+
text =
640+
Date(time)
641+
.format(
642+
model.preferences.dateFormatOverview.value,
643+
model.preferences.timeFormatOverview.value,
644+
)
645+
.let { lastBackupFormatted ->
646+
"${requireContext().getString(R.string.auto_backup_last)}: $lastBackupFormatted"
647+
}
648+
} else isVisible = false
649+
}
628650
}
629-
}
630651
binding.PeriodicBackupsPeriodInDays.setup(
631652
value.periodInDays,
632653
R.string.backup_period_days,

app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ import com.philkes.notallyx.presentation.view.note.audio.AudioAdapter
6969
import com.philkes.notallyx.presentation.view.note.preview.PreviewFileAdapter
7070
import com.philkes.notallyx.presentation.view.note.preview.PreviewImageAdapter
7171
import com.philkes.notallyx.presentation.viewmodel.NotallyModel
72-
import com.philkes.notallyx.presentation.viewmodel.preference.DateFormat
7372
import com.philkes.notallyx.presentation.viewmodel.preference.EditAction
7473
import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences
7574
import com.philkes.notallyx.presentation.viewmodel.preference.NotesSortBy
@@ -680,12 +679,13 @@ abstract class EditActivity(private val type: Type) : LockedActivity<ActivityEdi
680679
Pair(notallyModel.modifiedTimestamp, R.string.modified_date)
681680
else -> Pair(null, null)
682681
}
683-
val dateFormat =
684-
if (preferences.applyDateFormatInNoteView.value) {
685-
preferences.dateFormat.value
686-
} else DateFormat.ABSOLUTE
687682
binding.Date.apply {
688-
displayFormattedTimestamp(date, dateFormat, datePrefixResId)
683+
displayFormattedTimestamp(
684+
date,
685+
preferences.dateFormatNoteView.value,
686+
preferences.timeFormatNoteView.value,
687+
datePrefixResId,
688+
)
689689
setTextSizeSp(notallyModel.textSize.displaySmallerSize)
690690
}
691691
binding.EnterTitle.setText(notallyModel.title)
@@ -991,6 +991,8 @@ abstract class EditActivity(private val type: Type) : LockedActivity<ActivityEdi
991991
notallyModel.originalNote?.let { note ->
992992
binding.EditNoteReminderChip.setupReminderChip(
993993
note,
994+
preferences.dateFormatNoteView.value,
995+
preferences.timeFormatNoteView.value,
994996
notallyModel.textSize.displaySmallerSize,
995997
)
996998
binding.EditNoteReminderChip.setOnClickListener {

app/src/main/java/com/philkes/notallyx/presentation/activity/note/PickNoteActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ open class PickNoteActivity : LockedActivity<ActivityPickNoteBinding>(), ItemLis
5050
with(preferences) {
5151
BaseNoteAdapter(
5252
Collections.emptySet(),
53-
dateFormat.value,
53+
dateFormatOverview.value,
54+
timeFormatOverview.value,
5455
{ adapter -> notesSorting.value.createCallback(adapter) },
5556
BaseNoteVHPreferences(
5657
textSizeOverview.value,

0 commit comments

Comments
 (0)