From 87a3562a442bfedd70280fcdc6653179e1b7818a Mon Sep 17 00:00:00 2001 From: PhilKes Date: Sat, 11 Jan 2025 19:30:51 +0100 Subject: [PATCH] Add setting to optionally apply date format to note view --- .../settings/PreferenceBindingExtensions.kt | 56 +++++++++++++++++-- .../fragment/settings/SettingsFragment.kt | 18 ++++-- .../activity/note/EditActivity.kt | 7 ++- .../view/misc/StylableEditTextWithHistory.kt | 4 +- .../preference/NotallyXPreferences.kt | 2 + .../viewmodel/preference/Preference.kt | 5 ++ .../com/philkes/notallyx/utils/Extensions.kt | 7 +++ .../main/res/layout/dialog_date_format.xml | 35 ++++++++++++ ..._sort_dialog.xml => dialog_notes_sort.xml} | 0 ...alog.xml => dialog_preference_boolean.xml} | 0 ...input_dialog.xml => dialog_text_input.xml} | 0 ...t_dialog_2.xml => dialog_text_input_2.xml} | 0 app/src/main/res/values/strings.xml | 2 + 13 files changed, 122 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/layout/dialog_date_format.xml rename app/src/main/res/layout/{notes_sort_dialog.xml => dialog_notes_sort.xml} (100%) rename app/src/main/res/layout/{preference_boolean_dialog.xml => dialog_preference_boolean.xml} (100%) rename app/src/main/res/layout/{text_input_dialog.xml => dialog_text_input.xml} (100%) rename app/src/main/res/layout/{text_input_dialog_2.xml => dialog_text_input_2.xml} (100%) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt index 4d0faaed..9e2165d4 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/PreferenceBindingExtensions.kt @@ -12,11 +12,12 @@ import com.google.android.material.slider.Slider import com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE import com.philkes.notallyx.R import com.philkes.notallyx.databinding.ChoiceItemBinding -import com.philkes.notallyx.databinding.NotesSortDialogBinding +import com.philkes.notallyx.databinding.DialogDateFormatBinding +import com.philkes.notallyx.databinding.DialogNotesSortBinding +import com.philkes.notallyx.databinding.DialogPreferenceBooleanBinding +import com.philkes.notallyx.databinding.DialogTextInputBinding import com.philkes.notallyx.databinding.PreferenceBinding -import com.philkes.notallyx.databinding.PreferenceBooleanDialogBinding import com.philkes.notallyx.databinding.PreferenceSeekbarBinding -import com.philkes.notallyx.databinding.TextInputDialogBinding import com.philkes.notallyx.presentation.addCancelButton import com.philkes.notallyx.presentation.checkedTag import com.philkes.notallyx.presentation.showToast @@ -25,6 +26,7 @@ import com.philkes.notallyx.presentation.viewmodel.BaseNoteModel import com.philkes.notallyx.presentation.viewmodel.preference.BiometricLock import com.philkes.notallyx.presentation.viewmodel.preference.BooleanPreference import com.philkes.notallyx.presentation.viewmodel.preference.Constants.PASSWORD_EMPTY +import com.philkes.notallyx.presentation.viewmodel.preference.DateFormat import com.philkes.notallyx.presentation.viewmodel.preference.EnumPreference import com.philkes.notallyx.presentation.viewmodel.preference.IntPreference import com.philkes.notallyx.presentation.viewmodel.preference.NotallyXPreferences.Companion.EMPTY_PATH @@ -129,7 +131,7 @@ fun PreferenceBinding.setup( Value.text = value.getText(context) root.setOnClickListener { - val layout = NotesSortDialogBinding.inflate(layoutInflater, null, false) + val layout = DialogNotesSortBinding.inflate(layoutInflater, null, false) NotesSortBy.entries.forEachIndexed { idx, notesSortBy -> ChoiceItemBinding.inflate(layoutInflater).root.apply { id = idx @@ -174,6 +176,48 @@ fun PreferenceBinding.setup( } } +fun PreferenceBinding.setup( + dateFormatPreference: EnumPreference, + dateFormatValue: DateFormat, + applyToNoteViewValue: Boolean, + context: Context, + layoutInflater: LayoutInflater, + onSave: (dateFormat: DateFormat, applyToEditMode: Boolean) -> Unit, +) { + Title.setText(dateFormatPreference.titleResId!!) + + Value.text = dateFormatValue.getText(context) + + root.setOnClickListener { + val layout = DialogDateFormatBinding.inflate(layoutInflater, null, false) + DateFormat.entries.forEachIndexed { idx, dateFormat -> + ChoiceItemBinding.inflate(layoutInflater).root.apply { + id = idx + text = dateFormat.getText(context) + tag = dateFormat + layout.DateFormatRadioGroup.addView(this) + if (dateFormat == dateFormatValue) { + layout.DateFormatRadioGroup.check(this.id) + } + } + } + + layout.ApplyToNoteView.isChecked = applyToNoteViewValue + + MaterialAlertDialogBuilder(context) + .setTitle(dateFormatPreference.titleResId) + .setView(layout.root) + .setPositiveButton(R.string.save) { dialog, _ -> + dialog.cancel() + val dateFormat = layout.DateFormatRadioGroup.checkedTag() as DateFormat + val applyToNoteView = layout.ApplyToNoteView.isChecked + onSave(dateFormat, applyToNoteView) + } + .addCancelButton() + .show() + } +} + fun PreferenceBinding.setup( preference: BooleanPreference, value: Boolean, @@ -189,7 +233,7 @@ fun PreferenceBinding.setup( Value.text = if (value) enabledText else disabledText root.setOnClickListener { val layout = - PreferenceBooleanDialogBinding.inflate(layoutInflater, null, false).apply { + DialogPreferenceBooleanBinding.inflate(layoutInflater, null, false).apply { Title.setText(preference.titleResId) messageResId?.let { Message.setText(it) } if (value) { @@ -231,7 +275,7 @@ fun PreferenceBinding.setupBackupPassword( Value.text = if (password != PASSWORD_EMPTY) password else context.getText(R.string.tap_to_set_up) root.setOnClickListener { - val layout = TextInputDialogBinding.inflate(layoutInflater, null, false) + val layout = DialogTextInputBinding.inflate(layoutInflater, null, false) layout.InputText.apply { if (password != PASSWORD_EMPTY) { setText(password) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt index 5f7974b2..4fc85079 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/main/fragment/settings/SettingsFragment.kt @@ -23,8 +23,8 @@ import com.philkes.notallyx.NotallyXApplication import com.philkes.notallyx.R import com.philkes.notallyx.data.imports.FOLDER_MIMETYPE import com.philkes.notallyx.data.imports.ImportSource +import com.philkes.notallyx.databinding.DialogTextInputBinding import com.philkes.notallyx.databinding.FragmentSettingsBinding -import com.philkes.notallyx.databinding.TextInputDialogBinding import com.philkes.notallyx.presentation.addCancelButton import com.philkes.notallyx.presentation.getUriForFile import com.philkes.notallyx.presentation.setupImportProgressDialog @@ -150,7 +150,7 @@ class SettingsFragment : Fragment() { } "application/zip" -> { - val layout = TextInputDialogBinding.inflate(layoutInflater, null, false) + val layout = DialogTextInputBinding.inflate(layoutInflater, null, false) val password = model.preferences.backupPassword.value layout.InputText.apply { if (password != PASSWORD_EMPTY) { @@ -190,9 +190,17 @@ class SettingsFragment : Fragment() { } } - dateFormat.observe(viewLifecycleOwner) { value -> - binding.DateFormat.setup(dateFormat, value, requireContext()) { newValue -> - model.savePreference(dateFormat, newValue) + dateFormat.merge(applyDateFormatInNoteView).observe(viewLifecycleOwner) { + (dateFormatValue, applyDateFormatInEditNoteValue) -> + binding.DateFormat.setup( + dateFormat, + dateFormatValue, + applyDateFormatInEditNoteValue, + requireContext(), + layoutInflater, + ) { newDateFormatValue, newApplyDateFormatInEditNote -> + model.savePreference(dateFormat, newDateFormatValue) + model.savePreference(applyDateFormatInNoteView, newApplyDateFormatInEditNote) } } diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt index 9ed499af..3fb2e2db 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt @@ -58,6 +58,7 @@ import com.philkes.notallyx.presentation.view.note.audio.AudioAdapter import com.philkes.notallyx.presentation.view.note.preview.PreviewFileAdapter import com.philkes.notallyx.presentation.view.note.preview.PreviewImageAdapter import com.philkes.notallyx.presentation.viewmodel.NotallyModel +import com.philkes.notallyx.presentation.viewmodel.preference.DateFormat import com.philkes.notallyx.presentation.viewmodel.preference.NotesSortBy import com.philkes.notallyx.presentation.widget.WidgetProvider import com.philkes.notallyx.utils.FileError @@ -468,7 +469,11 @@ abstract class EditActivity(private val type: Type) : NotesSortBy.MODIFIED_DATE -> Pair(model.modifiedTimestamp, R.string.modified_date) else -> Pair(null, null) } - binding.Date.displayFormattedTimestamp(date, preferences.dateFormat.value, datePrefixResId) + val dateFormat = + if (preferences.applyDateFormatInNoteView.value) { + preferences.dateFormat.value + } else DateFormat.ABSOLUTE + binding.Date.displayFormattedTimestamp(date, dateFormat, datePrefixResId) binding.EnterTitle.setText(model.title) Operations.bindLabels(binding.LabelGroup, model.labels, model.textSize, paddingTop = true) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/misc/StylableEditTextWithHistory.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/misc/StylableEditTextWithHistory.kt index 4d4f8857..2e507e44 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/view/misc/StylableEditTextWithHistory.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/view/misc/StylableEditTextWithHistory.kt @@ -20,7 +20,7 @@ import com.philkes.notallyx.R import com.philkes.notallyx.data.model.findWebUrls import com.philkes.notallyx.data.model.isNoteUrl import com.philkes.notallyx.data.model.isWebUrl -import com.philkes.notallyx.databinding.TextInputDialog2Binding +import com.philkes.notallyx.databinding.DialogTextInput2Binding import com.philkes.notallyx.presentation.clone import com.philkes.notallyx.presentation.createTextWatcherWithHistory import com.philkes.notallyx.presentation.removeSelectionFromSpans @@ -341,7 +341,7 @@ class StylableEditTextWithHistory(context: Context, attrs: AttributeSet) : ) { val isNoteUrl = urlBefore.isNoteUrl() val layout = - TextInputDialog2Binding.inflate(LayoutInflater.from(context)).apply { + DialogTextInput2Binding.inflate(LayoutInflater.from(context)).apply { InputText1.setText(displayTextBefore) InputTextLayout1.setHint(R.string.display_text) InputText2.setText(urlBefore) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt index 7d664205..abc0b80b 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/NotallyXPreferences.kt @@ -35,6 +35,8 @@ class NotallyXPreferences private constructor(private val app: Application) { createEnumPreference(preferences, "textSize", TextSize.MEDIUM, R.string.text_size) val dateFormat = createEnumPreference(preferences, "dateFormat", DateFormat.RELATIVE, R.string.date_format) + val applyDateFormatInNoteView = + BooleanPreference("applyDateFormatInNoteView", preferences, true) val notesView = createEnumPreference(preferences, "view", NotesView.LIST, R.string.view) val notesSorting = NotesSortPreference(preferences) diff --git a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt index 1a17c579..b6182a3c 100644 --- a/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt +++ b/app/src/main/java/com/philkes/notallyx/presentation/viewmodel/preference/Preference.kt @@ -12,6 +12,7 @@ import com.philkes.notallyx.data.model.toPreservedByteArray import com.philkes.notallyx.data.model.toPreservedString import com.philkes.notallyx.presentation.view.misc.NotNullLiveData import com.philkes.notallyx.utils.createObserverSkipFirst +import com.philkes.notallyx.utils.merge import java.security.SecureRandom import java.util.Date import java.util.Locale @@ -60,6 +61,10 @@ abstract class BasePreference( getData().observe(lifecycleOwner, observer) } + fun merge(other: BasePreference): MediatorLiveData> { + return getData().merge(other.getData()) + } + fun observeForever(observer: Observer) { getData().observeForever(observer) } diff --git a/app/src/main/java/com/philkes/notallyx/utils/Extensions.kt b/app/src/main/java/com/philkes/notallyx/utils/Extensions.kt index 79821711..3d219be7 100644 --- a/app/src/main/java/com/philkes/notallyx/utils/Extensions.kt +++ b/app/src/main/java/com/philkes/notallyx/utils/Extensions.kt @@ -63,6 +63,13 @@ fun NotNullLiveData.mergeSkipFirst( } } +fun NotNullLiveData.merge(liveData: NotNullLiveData): MediatorLiveData> { + return MediatorLiveData>().apply { + addSource(this@merge) { value1 -> value = Pair(value1, liveData.value) } + addSource(liveData) { value2 -> value = Pair(this@merge.value, value2) } + } +} + fun ClipboardManager.getLatestText(): CharSequence? { return primaryClip?.let { if (it.itemCount > 0) it.getItemAt(0)!!.text else null } } diff --git a/app/src/main/res/layout/dialog_date_format.xml b/app/src/main/res/layout/dialog_date_format.xml new file mode 100644 index 00000000..a50bd281 --- /dev/null +++ b/app/src/main/res/layout/dialog_date_format.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/notes_sort_dialog.xml b/app/src/main/res/layout/dialog_notes_sort.xml similarity index 100% rename from app/src/main/res/layout/notes_sort_dialog.xml rename to app/src/main/res/layout/dialog_notes_sort.xml diff --git a/app/src/main/res/layout/preference_boolean_dialog.xml b/app/src/main/res/layout/dialog_preference_boolean.xml similarity index 100% rename from app/src/main/res/layout/preference_boolean_dialog.xml rename to app/src/main/res/layout/dialog_preference_boolean.xml diff --git a/app/src/main/res/layout/text_input_dialog.xml b/app/src/main/res/layout/dialog_text_input.xml similarity index 100% rename from app/src/main/res/layout/text_input_dialog.xml rename to app/src/main/res/layout/dialog_text_input.xml diff --git a/app/src/main/res/layout/text_input_dialog_2.xml b/app/src/main/res/layout/dialog_text_input_2.xml similarity index 100% rename from app/src/main/res/layout/text_input_dialog_2.xml rename to app/src/main/res/layout/dialog_text_input_2.xml diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5c39b040..ce5a68f2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -140,6 +140,8 @@ Follow system Date format + Applies selected date format in Notes Overview + Also apply in Note View None Text size