From 0e205e6cb37496709e83414930fae1b53c1d7e40 Mon Sep 17 00:00:00 2001 From: merkost Date: Sat, 15 Jul 2023 13:52:03 +1000 Subject: [PATCH] Added new backup dialogs --- .../adapters/FilterContactSourcesAdapter.kt | 2 +- .../pro/dialogs/DateTimePatternInfoDialog.kt | 18 +++ .../pro/dialogs/ManageAutoBackupsDialog.kt | 138 ++++++++++++++++++ .../pro/dialogs/SelectContactTypesDialog.kt | 82 +++++++++++ .../layout/datetime_pattern_info_layout.xml | 9 ++ .../dialog_manage_automatic_backups.xml | 84 +++++++++++ 6 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/DateTimePatternInfoDialog.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageAutoBackupsDialog.kt create mode 100644 app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactTypesDialog.kt create mode 100644 app/src/main/res/layout/datetime_pattern_info_layout.xml create mode 100644 app/src/main/res/layout/dialog_manage_automatic_backups.xml diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt index ceb5f091..3af91af1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/adapters/FilterContactSourcesAdapter.kt @@ -15,7 +15,7 @@ import kotlinx.android.synthetic.main.item_filter_contact_source.view.* class FilterContactSourcesAdapter( val activity: SimpleActivity, private val contactSources: List, - private val displayContactSources: ArrayList + private val displayContactSources: List ) : RecyclerView.Adapter() { private val selectedKeys = HashSet() diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/DateTimePatternInfoDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/DateTimePatternInfoDialog.kt new file mode 100644 index 00000000..ad5cd722 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/DateTimePatternInfoDialog.kt @@ -0,0 +1,18 @@ +package com.simplemobiletools.contacts.pro.dialogs + +import com.simplemobiletools.commons.activities.BaseSimpleActivity +import com.simplemobiletools.commons.extensions.getAlertDialogBuilder +import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.contacts.pro.R + +class DateTimePatternInfoDialog(activity: BaseSimpleActivity) { + + init { + val view = activity.layoutInflater.inflate(R.layout.datetime_pattern_info_layout, null) + activity.getAlertDialogBuilder() + .setPositiveButton(R.string.ok) { _, _ -> { } } + .apply { + activity.setupDialogStuff(view, this) + } + } +} diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageAutoBackupsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageAutoBackupsDialog.kt new file mode 100644 index 00000000..555370b7 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/ManageAutoBackupsDialog.kt @@ -0,0 +1,138 @@ +package com.simplemobiletools.contacts.pro.dialogs + +import android.view.ViewGroup +import androidx.appcompat.app.AlertDialog +import com.simplemobiletools.commons.dialogs.FilePickerDialog +import com.simplemobiletools.commons.extensions.getAlertDialogBuilder +import com.simplemobiletools.commons.extensions.hideKeyboard +import com.simplemobiletools.commons.extensions.humanizePath +import com.simplemobiletools.commons.extensions.isAValidFilename +import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.extensions.toast +import com.simplemobiletools.commons.extensions.value +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.helpers.ensureBackgroundThread +import com.simplemobiletools.commons.models.contacts.ContactSource +import com.simplemobiletools.contacts.pro.R +import com.simplemobiletools.contacts.pro.activities.SimpleActivity +import com.simplemobiletools.contacts.pro.extensions.config +import kotlinx.android.synthetic.main.dialog_manage_automatic_backups.view.backup_events_filename +import kotlinx.android.synthetic.main.dialog_manage_automatic_backups.view.backup_events_filename_hint +import kotlinx.android.synthetic.main.dialog_manage_automatic_backups.view.backup_events_folder +import kotlinx.android.synthetic.main.dialog_manage_automatic_backups.view.manage_event_types_holder +import java.io.File + +class ManageAutoBackupsDialog(private val activity: SimpleActivity, onSuccess: () -> Unit) { + private val view = (activity.layoutInflater.inflate(R.layout.dialog_manage_automatic_backups, null) as ViewGroup) + private val config = activity.config + private var backupFolder = config.autoBackupFolder + private var selectedContactTypes = HashSet() + + private fun setContactTypes() { + ContactsHelper(activity).getContactSources { contactSources -> + val availableContactSources = contactSources.toSet() + if (config.autoBackupContactSources.isEmpty()) { + selectedContactTypes = contactSources.toHashSet() + } else { + selectedContactTypes = availableContactSources.filter { it.name in config.autoBackupContactSources }.toHashSet() + } + } + } + + init { + setContactTypes() + view.apply { + backup_events_folder.setText(activity.humanizePath(backupFolder)) + val filename = config.autoBackupFilename.ifEmpty { + "${activity.getString(R.string.contacts)}_%Y%M%D_%h%m%s" + } + + backup_events_filename.setText(filename) + backup_events_filename_hint.setEndIconOnClickListener { + DateTimePatternInfoDialog(activity) + } + + backup_events_filename_hint.setEndIconOnLongClickListener { + DateTimePatternInfoDialog(activity) + true + } + + backup_events_folder.setOnClickListener { + selectBackupFolder() + } + + manage_event_types_holder.setOnClickListener { + activity.runOnUiThread { + SelectContactTypesDialog(activity, selectedContactTypes.map { it.name }) { + selectedContactTypes = it + config.autoBackupContactSources = it.map { it.name }.toSet() + } + } + } + } + activity.getAlertDialogBuilder() + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.cancel, null) + .apply { + activity.setupDialogStuff(view, this, R.string.manage_automatic_backups) { dialog -> + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + val filename = view.backup_events_filename.value + when { + filename.isEmpty() -> activity.toast(R.string.empty_name) + filename.isAValidFilename() -> { + val file = File(backupFolder, "$filename.ics") + if (file.exists() && !file.canWrite()) { + activity.toast(R.string.name_taken) + return@setOnClickListener + } + + if (selectedContactTypes.isEmpty()) { + activity.toast(R.string.no_entries_for_exporting) + return@setOnClickListener + } + + ensureBackgroundThread { + config.apply { + autoBackupFolder = backupFolder + autoBackupFilename = filename + if (autoBackupContactSources != selectedContactTypes) { + autoBackupContactSources = selectedContactTypes.map { it.type }.toSet() + } + } + + activity.runOnUiThread { + onSuccess() + } + + dialog.dismiss() + } + } + + else -> activity.toast(R.string.invalid_name) + } + } + } + } + } + + private fun selectBackupFolder() { + activity.hideKeyboard(view.backup_events_filename) + FilePickerDialog(activity, backupFolder, false, showFAB = true) { path -> + activity.handleSAFDialog(path) { grantedSAF -> + if (!grantedSAF) { + return@handleSAFDialog + } + + activity.handleSAFDialogSdk30(path) { grantedSAF30 -> + if (!grantedSAF30) { + return@handleSAFDialogSdk30 + } + + backupFolder = path + view.backup_events_folder.setText(activity.humanizePath(path)) + } + } + } + } +} + diff --git a/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactTypesDialog.kt b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactTypesDialog.kt new file mode 100644 index 00000000..93d7d83d --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/contacts/pro/dialogs/SelectContactTypesDialog.kt @@ -0,0 +1,82 @@ +package com.simplemobiletools.contacts.pro.dialogs + +import androidx.appcompat.app.AlertDialog +import com.simplemobiletools.commons.extensions.getAlertDialogBuilder +import com.simplemobiletools.commons.extensions.setupDialogStuff +import com.simplemobiletools.commons.helpers.ContactsHelper +import com.simplemobiletools.commons.models.contacts.Contact +import com.simplemobiletools.commons.models.contacts.ContactSource +import com.simplemobiletools.contacts.pro.R +import com.simplemobiletools.contacts.pro.activities.SimpleActivity +import com.simplemobiletools.contacts.pro.adapters.FilterContactSourcesAdapter +import kotlinx.android.synthetic.main.dialog_filter_contact_sources.view.filter_contact_sources_list + +class SelectContactTypesDialog( + val activity: SimpleActivity, + private val selectedContactTypes: List, + val callback: (HashSet) -> Unit +) { + private var dialog: AlertDialog? = null + private val view = activity.layoutInflater.inflate(R.layout.dialog_filter_contact_sources, null) + + private var contactSources = mutableListOf() + private var contacts = listOf() + private var isContactSourcesReady = false + private var isContactsReady = false + + init { + ContactsHelper(activity).getContactSources { sources -> + contactSources = sources + isContactSourcesReady = true + processDataIfReady() + } + + ContactsHelper(activity).getContacts(getAll = true) { receivedContacts -> + contacts = receivedContacts + isContactsReady = true + processDataIfReady() + } + } + + private fun processDataIfReady() { + if (!isContactSourcesReady) { + return + } + + val contactSourcesWithCount = mutableListOf() + for (contactSource in contactSources) { + val count = if (isContactsReady) { + contacts.count { it.source == contactSource.name } + } else { + -1 + } + contactSourcesWithCount.add(contactSource.copy(count = count)) + } + + contactSources.clear() + contactSources.addAll(contactSourcesWithCount) + + activity.runOnUiThread { + view.filter_contact_sources_list.adapter = FilterContactSourcesAdapter(activity, contactSourcesWithCount, selectedContactTypes.toList()) + if (dialog == null) { + activity.runOnUiThread { + activity.getAlertDialogBuilder() + .setPositiveButton(R.string.ok) { _, _ -> confirmContactTypes() } + .setNegativeButton(R.string.cancel, null) + .apply { + activity.setupDialogStuff(view, this) { alertDialog -> + dialog = alertDialog + } + } + } + } + } + } + + private fun confirmContactTypes() { + val adapter = view.filter_contact_sources_list.adapter as FilterContactSourcesAdapter + val selectedItems = adapter.getSelectedContactSources() + callback(selectedItems.toHashSet()) + dialog?.dismiss() + } +} diff --git a/app/src/main/res/layout/datetime_pattern_info_layout.xml b/app/src/main/res/layout/datetime_pattern_info_layout.xml new file mode 100644 index 00000000..36ee34d1 --- /dev/null +++ b/app/src/main/res/layout/datetime_pattern_info_layout.xml @@ -0,0 +1,9 @@ + + diff --git a/app/src/main/res/layout/dialog_manage_automatic_backups.xml b/app/src/main/res/layout/dialog_manage_automatic_backups.xml new file mode 100644 index 00000000..64e59a6b --- /dev/null +++ b/app/src/main/res/layout/dialog_manage_automatic_backups.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + +