Pass group icon selection and time through viewmodel

This commit is contained in:
J-Jamet
2021-08-05 20:09:38 +02:00
parent c8445fb711
commit 78c39edceb
7 changed files with 181 additions and 131 deletions

View File

@@ -171,9 +171,15 @@ class EntryEditActivity : LockingActivity(),
mEntryEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) {
selectTime(dateInstant)
// Launch the time picker
val dateTime = DateTime(dateInstant.date)
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour)
.show(supportFragmentManager, "TimePickerFragment")
} else {
selectDate(dateInstant)
// Launch the date picker
val dateTime = DateTime(dateInstant.date)
DatePickerFragment.getInstance(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth)
.show(supportFragmentManager, "DatePickerFragment")
}
}
@@ -587,25 +593,6 @@ class EntryEditActivity : LockingActivity(),
return super.onOptionsItemSelected(item)
}
// Launch the date picker
private fun selectDate(dateInstant: DateInstant) {
val dateTime = DateTime(dateInstant.date)
val defaultYear = dateTime.year
val defaultMonth = dateTime.monthOfYear - 1
val defaultDay = dateTime.dayOfMonth
DatePickerFragment.getInstance(defaultYear, defaultMonth, defaultDay)
.show(supportFragmentManager, "DatePickerFragment")
}
// Launch the time picker
private fun selectTime(dateInstant: DateInstant) {
val dateTime = DateTime(dateInstant.date)
val defaultHour = dateTime.hourOfDay
val defaultMinute = dateTime.minuteOfHour
TimePickerFragment.getInstance(defaultHour, defaultMinute)
.show(supportFragmentManager, "TimePickerFragment")
}
override fun onDateSet(datePicker: DatePicker?, year: Int, month: Int, day: Int) {
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice

View File

@@ -77,6 +77,7 @@ import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.MenuUtil
import com.kunzisoft.keepass.view.*
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
import com.kunzisoft.keepass.viewmodels.GroupViewModel
import org.joda.time.DateTime
@@ -102,6 +103,7 @@ class GroupActivity : LockingActivity(),
private var groupNameView: TextView? = null
private val mGroupViewModel: GroupViewModel by viewModels()
private val mGroupEditViewModel: GroupEditViewModel by viewModels()
// TODO Remove and pass through viewModel
private var mGroupFragment: GroupFragment? = null
@@ -280,6 +282,24 @@ class GroupActivity : LockingActivity(),
Log.i(TAG, "Finished creating tree")
}
mGroupEditViewModel.requestIconSelection.observe(this) { iconImage ->
IconPickerActivity.launch(this@GroupActivity, iconImage)
}
mGroupEditViewModel.requestDateTimeSelection.observe(this) { dateInstant ->
if (dateInstant.type == DateInstant.Type.TIME) {
// Launch the time picker
val dateTime = DateTime(dateInstant.date)
TimePickerFragment.getInstance(dateTime.hourOfDay, dateTime.minuteOfHour)
.show(supportFragmentManager, "TimePickerFragment")
} else {
// Launch the date picker
val dateTime = DateTime(dateInstant.date)
DatePickerFragment.getInstance(dateTime.year, dateTime.monthOfYear - 1, dateTime.dayOfMonth)
.show(supportFragmentManager, "DatePickerFragment")
}
}
}
override fun onDatabaseRetrieved(database: Database?) {
@@ -686,33 +706,12 @@ class GroupActivity : LockingActivity(),
// To fix android 4.4 issue
// https://stackoverflow.com/questions/12436073/datepicker-ondatechangedlistener-called-twice
if (datePicker?.isShown == true) {
val groupEditFragment = supportFragmentManager.findFragmentByTag(GroupEditDialogFragment.TAG_CREATE_GROUP) as? GroupEditDialogFragment
groupEditFragment?.getExpiryTime()?.date?.let { expiresDate ->
groupEditFragment.setExpiryTime(DateInstant(DateTime(expiresDate)
.withYear(year)
.withMonthOfYear(month + 1)
.withDayOfMonth(day)
.toDate()))
// Launch the time picker
val dateTime = DateTime(expiresDate)
val defaultHour = dateTime.hourOfDay
val defaultMinute = dateTime.minuteOfHour
TimePickerFragment.getInstance(defaultHour, defaultMinute)
.show(supportFragmentManager, "TimePickerFragment")
}
mGroupEditViewModel.selectDate(year, month, day)
}
}
override fun onTimeSet(view: TimePicker?, hours: Int, minutes: Int) {
val groupEditFragment = supportFragmentManager.findFragmentByTag(GroupEditDialogFragment.TAG_CREATE_GROUP) as? GroupEditDialogFragment
groupEditFragment?.getExpiryTime()?.date?.let { expiresDate ->
// Save the date
groupEditFragment.setExpiryTime(
DateInstant(DateTime(expiresDate)
.withHourOfDay(hours)
.withMinuteOfHour(minutes)
.toDate()))
}
mGroupEditViewModel.selectTime(hours, minutes)
}
private fun finishNodeAction() {
@@ -1059,9 +1058,7 @@ class GroupActivity : LockingActivity(),
// To create tree dialog for icon
IconPickerActivity.onActivityResult(requestCode, resultCode, data) { icon ->
(supportFragmentManager
.findFragmentByTag(GroupEditDialogFragment.TAG_CREATE_GROUP) as GroupEditDialogFragment)
.setIcon(icon)
mGroupEditViewModel.selectIcon(icon)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

View File

@@ -28,28 +28,31 @@ import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import com.google.android.material.textfield.TextInputLayout
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.IconPickerActivity
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment.EditGroupDialogAction.CREATION
import com.kunzisoft.keepass.activities.dialogs.GroupEditDialogFragment.EditGroupDialogAction.UPDATE
import com.kunzisoft.keepass.activities.fragments.DatabaseDialogFragment
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.model.GroupInfo
import com.kunzisoft.keepass.view.DateTimeEditFieldView
import com.kunzisoft.keepass.viewmodels.GroupEditViewModel
import org.joda.time.DateTime
class GroupEditDialogFragment : DialogFragment() {
class GroupEditDialogFragment : DatabaseDialogFragment() {
private var mEditGroupListener: EditGroupListener? = null
private val mGroupEditViewModel: GroupEditViewModel by activityViewModels()
private var populateIconMethod: ((ImageView, IconImage) -> Unit)? = null
private var mEditGroupDialogAction = EditGroupDialogAction.NONE
private var mGroupInfo = GroupInfo()
private lateinit var iconButtonView: ImageView
private var iconColor: Int = 0
private var mIconColor: Int = 0
private lateinit var nameTextLayoutView: TextInputLayout
private lateinit var nameTextView: TextView
private lateinit var notesTextLayoutView: TextInputLayout
@@ -74,8 +77,10 @@ class GroupEditDialogFragment : DialogFragment() {
mEditGroupListener = context as EditGroupListener
} catch (e: ClassCastException) {
// The activity doesn't implement the interface, throw exception
throw ClassCastException(context.toString()
+ " must implement " + GroupEditDialogFragment::class.java.name)
throw ClassCastException(
context.toString()
+ " must implement " + GroupEditDialogFragment::class.java.name
)
}
}
@@ -84,6 +89,48 @@ class GroupEditDialogFragment : DialogFragment() {
super.onDetach()
}
override fun onDatabaseRetrieved(database: Database?) {
populateIconMethod = { imageView, icon ->
database?.iconDrawableFactory?.assignDatabaseIcon(imageView, icon, mIconColor)
}
populateIconMethod?.invoke(iconButtonView, mGroupInfo.icon)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mGroupEditViewModel.onIconSelected.observe(this) { iconImage ->
mGroupInfo.icon = iconImage
populateIconMethod?.invoke(iconButtonView, mGroupInfo.icon)
}
mGroupEditViewModel.onDateSelected.observe(this) { viewModelDate ->
// Save the date
mGroupInfo.expiryTime = DateInstant(
DateTime(mGroupInfo.expiryTime.date)
.withYear(viewModelDate.year)
.withMonthOfYear(viewModelDate.month + 1)
.withDayOfMonth(viewModelDate.day)
.toDate())
expirationView.dateTime = mGroupInfo.expiryTime
if (expirationView.dateTime.type == DateInstant.Type.DATE_TIME) {
val instantTime = DateInstant(mGroupInfo.expiryTime.date, DateInstant.Type.TIME)
// Trick to recall selection with time
mGroupEditViewModel.requestDateTimeSelection(instantTime)
}
}
mGroupEditViewModel.onTimeSelected.observe(this) { viewModelTime ->
// Save the time
mGroupInfo.expiryTime = DateInstant(
DateTime(mGroupInfo.expiryTime.date)
.withHourOfDay(viewModelTime.hours)
.withMinuteOfHour(viewModelTime.minutes)
.toDate(), mGroupInfo.expiryTime.type)
expirationView.dateTime = mGroupInfo.expiryTime
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
activity?.let { activity ->
val root = activity.layoutInflater.inflate(R.layout.fragment_group_edit, null)
@@ -96,7 +143,7 @@ class GroupEditDialogFragment : DialogFragment() {
// Retrieve the textColor to tint the icon
val ta = activity.theme.obtainStyledAttributes(intArrayOf(android.R.attr.textColor))
iconColor = ta.getColor(0, Color.WHITE)
mIconColor = ta.getColor(0, Color.WHITE)
ta.recycle()
if (savedInstanceState != null
@@ -115,16 +162,13 @@ class GroupEditDialogFragment : DialogFragment() {
}
// populate info in views
populateInfoToViews()
expirationView.setOnDateClickListener = {
expirationView.dateTime.date.let { expiresDate ->
val dateTime = DateTime(expiresDate)
val defaultYear = dateTime.year
val defaultMonth = dateTime.monthOfYear-1
val defaultDay = dateTime.dayOfMonth
DatePickerFragment.getInstance(defaultYear, defaultMonth, defaultDay)
.show(parentFragmentManager, "DatePickerFragment")
populateInfoToViews(mGroupInfo)
iconButtonView.setOnClickListener { _ ->
mGroupEditViewModel.requestIconSelection(mGroupInfo.icon)
}
expirationView.setOnDateClickListener = { dateInstant ->
mGroupEditViewModel.requestDateTimeSelection(dateInstant)
}
val builder = AlertDialog.Builder(activity)
@@ -137,10 +181,6 @@ class GroupEditDialogFragment : DialogFragment() {
mGroupInfo)
}
iconButtonView.setOnClickListener { _ ->
IconPickerActivity.launch(activity, mGroupInfo.icon)
}
return builder.create()
}
return super.onCreateDialog(savedInstanceState)
@@ -165,25 +205,15 @@ class GroupEditDialogFragment : DialogFragment() {
}
}
fun getExpiryTime(): DateInstant {
retrieveGroupInfoFromViews()
return mGroupInfo.expiryTime
}
fun setExpiryTime(expiryTime: DateInstant) {
mGroupInfo.expiryTime = expiryTime
populateInfoToViews()
}
private fun populateInfoToViews() {
assignIconView()
nameTextView.text = mGroupInfo.title
notesTextLayoutView.visibility = if (mGroupInfo.notes == null) View.GONE else View.VISIBLE
mGroupInfo.notes?.let {
private fun populateInfoToViews(groupInfo: GroupInfo) {
mGroupEditViewModel.selectIcon(groupInfo.icon)
nameTextView.text = groupInfo.title
notesTextLayoutView.visibility = if (groupInfo.notes == null) View.GONE else View.VISIBLE
groupInfo.notes?.let {
notesTextView.text = it
}
expirationView.activation = mGroupInfo.expires
expirationView.dateTime = mGroupInfo.expiryTime
expirationView.activation = groupInfo.expires
expirationView.dateTime = groupInfo.expiryTime
}
private fun retrieveGroupInfoFromViews() {
@@ -197,16 +227,6 @@ class GroupEditDialogFragment : DialogFragment() {
mGroupInfo.expiryTime = expirationView.dateTime
}
private fun assignIconView() {
// TODO Database
Database.getInstance()?.iconDrawableFactory?.assignDatabaseIcon(iconButtonView, mGroupInfo.icon, iconColor)
}
fun setIcon(icon: IconImage) {
mGroupInfo.icon = icon
assignIconView()
}
override fun onSaveInstanceState(outState: Bundle) {
retrieveGroupInfoFromViews()
outState.putInt(KEY_ACTION_ID, mEditGroupDialogAction.ordinal)

View File

@@ -0,0 +1,31 @@
package com.kunzisoft.keepass.activities.fragments
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels
import com.kunzisoft.keepass.activities.DatabaseRetrieval
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.viewmodels.DatabaseViewModel
abstract class DatabaseDialogFragment : DialogFragment(), DatabaseRetrieval {
private val mDatabaseViewModel: DatabaseViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mDatabaseViewModel.database.observe(this) { database ->
// TODO requireView().resetAppTimeoutWhenViewFocusedOrChanged(requireContext(), database)
onDatabaseRetrieved(database)
}
}
override fun onDatabaseActionFinished(
database: Database,
actionTask: String,
result: ActionRunnable.Result
) {
// Can be overridden by a subclass
}
}

View File

@@ -3,7 +3,6 @@ package com.kunzisoft.keepass.viewmodels
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.kunzisoft.keepass.app.database.IOActionTask
import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.database.element.icon.IconImage
@@ -12,13 +11,12 @@ import com.kunzisoft.keepass.database.element.node.NodeId
import com.kunzisoft.keepass.database.element.template.Template
import com.kunzisoft.keepass.model.*
import com.kunzisoft.keepass.otp.OtpElement
import com.kunzisoft.keepass.view.DataDate
import com.kunzisoft.keepass.view.DataTime
import java.util.*
class EntryEditViewModel: ViewModel() {
class EntryEditViewModel: NodeEditViewModel() {
// TODO Better variable implementation
private var mDatabase: Database? = null
private var mParent: Group? = null
private var mEntry: Entry? = null
@@ -39,11 +37,6 @@ class EntryEditViewModel: ViewModel() {
val onTemplateChanged : LiveData<Template> get() = _onTemplateChanged
private val _onTemplateChanged = SingleLiveEvent<Template>()
val requestIconSelection : LiveData<IconImage> get() = _requestIconSelection
private val _requestIconSelection = SingleLiveEvent<IconImage>()
val onIconSelected : LiveData<IconImage> get() = _onIconSelected
private val _onIconSelected = SingleLiveEvent<IconImage>()
val requestPasswordSelection : LiveData<Field> get() = _requestPasswordSelection
private val _requestPasswordSelection = SingleLiveEvent<Field>()
val onPasswordSelected : LiveData<Field> get() = _onPasswordSelected
@@ -56,13 +49,6 @@ class EntryEditViewModel: ViewModel() {
val onCustomFieldError : LiveData<Void?> get() = _onCustomFieldError
private val _onCustomFieldError = SingleLiveEvent<Void?>()
val requestDateTimeSelection : LiveData<DateInstant> get() = _requestDateTimeSelection
private val _requestDateTimeSelection = SingleLiveEvent<DateInstant>()
val onDateSelected : LiveData<DataDate> get() = _onDateSelected
private val _onDateSelected = SingleLiveEvent<DataDate>()
val onTimeSelected : LiveData<DataTime> get() = _onTimeSelected
private val _onTimeSelected = SingleLiveEvent<DataTime>()
val requestSetupOtp : LiveData<Void?> get() = _requestSetupOtp
private val _requestSetupOtp = SingleLiveEvent<Void?>()
val onOtpCreated : LiveData<OtpElement> get() = _onOtpCreated
@@ -287,14 +273,6 @@ class EntryEditViewModel: ViewModel() {
}
}
fun requestIconSelection(oldIconImage: IconImage) {
_requestIconSelection.value = oldIconImage
}
fun selectIcon(iconImage: IconImage) {
_onIconSelected.value = iconImage
}
fun requestPasswordSelection(passwordField: Field) {
_requestPasswordSelection.value = passwordField
}
@@ -323,18 +301,6 @@ class EntryEditViewModel: ViewModel() {
_onCustomFieldError.call()
}
fun requestDateTimeSelection(dateInstant: DateInstant) {
_requestDateTimeSelection.value = dateInstant
}
fun selectDate(year: Int, month: Int, day: Int) {
_onDateSelected.value = DataDate(year, month, day)
}
fun selectTime(hours: Int, minutes: Int) {
_onTimeSelected.value = DataTime(hours, minutes)
}
fun setupOtp() {
_requestSetupOtp.call()
}

View File

@@ -0,0 +1,6 @@
package com.kunzisoft.keepass.viewmodels
class GroupEditViewModel: NodeEditViewModel() {
// TODO Move fragment listeners
}

View File

@@ -0,0 +1,43 @@
package com.kunzisoft.keepass.viewmodels
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.icon.IconImage
import com.kunzisoft.keepass.view.DataDate
import com.kunzisoft.keepass.view.DataTime
abstract class NodeEditViewModel : ViewModel() {
val requestIconSelection : LiveData<IconImage> get() = _requestIconSelection
private val _requestIconSelection = SingleLiveEvent<IconImage>()
val onIconSelected : LiveData<IconImage> get() = _onIconSelected
private val _onIconSelected = SingleLiveEvent<IconImage>()
val requestDateTimeSelection : LiveData<DateInstant> get() = _requestDateTimeSelection
private val _requestDateTimeSelection = SingleLiveEvent<DateInstant>()
val onDateSelected : LiveData<DataDate> get() = _onDateSelected
private val _onDateSelected = SingleLiveEvent<DataDate>()
val onTimeSelected : LiveData<DataTime> get() = _onTimeSelected
private val _onTimeSelected = SingleLiveEvent<DataTime>()
fun requestIconSelection(oldIconImage: IconImage) {
_requestIconSelection.value = oldIconImage
}
fun selectIcon(iconImage: IconImage) {
_onIconSelected.value = iconImage
}
fun requestDateTimeSelection(dateInstant: DateInstant) {
_requestDateTimeSelection.value = dateInstant
}
fun selectDate(year: Int, month: Int, day: Int) {
_onDateSelected.value = DataDate(year, month, day)
}
fun selectTime(hours: Int, minutes: Int) {
_onTimeSelected.value = DataTime(hours, minutes)
}
}