From cb3bb583196f1c139903daee42c20523d79a12ba Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Wed, 23 Feb 2022 10:11:14 +0100 Subject: [PATCH] fix: treatments persist selection on scrolling --- .../fragments/TreatmentsBolusCarbsFragment.kt | 62 ++++++++++--------- .../fragments/TreatmentsCareportalFragment.kt | 47 +++++++------- .../TreatmentsExtendedBolusesFragment.kt | 39 +++++++----- .../TreatmentsProfileSwitchFragment.kt | 42 +++++++------ .../fragments/TreatmentsTempTargetFragment.kt | 47 +++++++------- .../TreatmentsTemporaryBasalsFragment.kt | 44 +++++++------ 6 files changed, 157 insertions(+), 124 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt index 5840cc1a35..1323b23113 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsBolusCarbsFragment.kt @@ -3,10 +3,13 @@ package info.nightscout.androidaps.activities.fragments import android.annotation.SuppressLint import android.graphics.Paint import android.os.Bundle +import android.util.Log +import android.util.SparseArray import android.view.* import android.widget.CompoundButton import android.view.ActionMode import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -68,6 +71,10 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { @Inject lateinit var repository: AppRepository @Inject lateinit var activePlugin: ActivePlugin + private var _binding: TreatmentsBolusCarbsFragmentBinding? = null + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! + class MealLink( val bolus: Bolus? = null, val carbs: Carbs? = null, @@ -75,17 +82,11 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { ) private val disposable = CompositeDisposable() - private val millsToThePast = T.days(30).msecs() - private var _binding: TreatmentsBolusCarbsFragmentBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var removeActionMode: ActionMode? = null - private var toolbar: Toolbar? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = @@ -253,21 +254,22 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { holder.binding.carbsPump.visibility = (carbs.interfaceIDs.pumpId != null).toVisibility() holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility() } - - val onChange = CompoundButton.OnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(ml) - } else { - selectedItems.remove(ml) - } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) - } - holder.binding.cbBolusRemove.visibility = ((ml.bolus?.isValid == true) && removeActionMode != null).toVisibility() - holder.binding.cbBolusRemove.setOnCheckedChangeListener(onChange) - + holder.binding.cbBolusRemove.visibility = (ml.bolus?.isValid == true && removeActionMode != null).toVisibility() holder.binding.cbCarbsRemove.visibility = (ml.carbs?.isValid == true && removeActionMode != null).toVisibility() - holder.binding.cbCarbsRemove.setOnCheckedChangeListener(onChange) - + if (removeActionMode != null) { + val onChange = CompoundButton.OnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, ml) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) + } + holder.binding.cbBolusRemove.setOnCheckedChangeListener(onChange) + holder.binding.cbBolusRemove.isChecked = selectedItems.get(position) != null + holder.binding.cbCarbsRemove.setOnCheckedChangeListener(onChange) + holder.binding.cbCarbsRemove.isChecked = selectedItems.get(position) != null + } holder.binding.calculation.tag = ml val nextTimestamp = if (mealLinks.size != position + 1) timestamp(mealLinks[position + 1]) else 0L holder.binding.delimiter.visibility = dateUtil.isSameDay(timestamp(ml), nextTimestamp).toVisibility() @@ -425,8 +427,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -437,7 +439,6 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -452,8 +453,8 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { - val mealLink = selectedItems.first() + if (selectedItems.size() == 1) { + val mealLink = selectedItems.valueAt(0) val bolus = mealLink.bolus if (bolus != null) return rh.gs(R.string.configbuilder_insulin) + ": " + rh.gs(R.string.formatinsulinunits, bolus.amount) + "\n" + @@ -463,14 +464,14 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { return rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carbs.amount.toInt()) + "\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(carbs.timestamp) } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } fun removeSelected() { - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { ml -> + selectedItems.forEach {key, ml -> ml.bolus?.let { bolus -> uel.log( Action.BOLUS_REMOVED, Sources.Treatments, @@ -496,7 +497,10 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() { ) } } + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt index b2230d9caa..d2069a504b 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsCareportalFragment.kt @@ -1,9 +1,11 @@ package info.nightscout.androidaps.activities.fragments import android.os.Bundle +import android.util.SparseArray import android.view.* import android.view.ActionMode import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -56,18 +58,17 @@ class TreatmentsCareportalFragment : DaggerFragment() { @Inject lateinit var repository: AppRepository @Inject lateinit var uel: UserEntryLogger - private val disposable = CompositeDisposable() + private var _binding: TreatmentsCareportalFragmentBinding? = null + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! + private val disposable = CompositeDisposable() private val millsToThePast = T.days(30).msecs() - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var toolbar: Toolbar? = null private var removeActionMode: ActionMode? = null - private var _binding: TreatmentsCareportalFragmentBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = TreatmentsCareportalFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root @@ -172,13 +173,16 @@ class TreatmentsCareportalFragment : DaggerFragment() { holder.binding.note.text = therapyEvent.note holder.binding.type.text = translator.translate(therapyEvent.type) holder.binding.cbRemove.visibility = (therapyEvent.isValid && removeActionMode != null).toVisibility() - holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(therapyEvent) - } else { - selectedItems.remove(therapyEvent) + if (removeActionMode != null) { + holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, therapyEvent) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) + holder.binding.cbRemove.isChecked = selectedItems.get(position) != null } val nextTimestamp = if (therapyList.size != position + 1) therapyList[position + 1].timestamp else 0L holder.binding.delimiter.visibility = dateUtil.isSameDay(therapyEvent.timestamp, nextTimestamp).toVisibility() @@ -243,8 +247,8 @@ class TreatmentsCareportalFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -255,7 +259,6 @@ class TreatmentsCareportalFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -270,20 +273,20 @@ class TreatmentsCareportalFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { - val therapyEvent = selectedItems.first() + if (selectedItems.size() == 1) { + val therapyEvent = selectedItems.valueAt(0) return rh.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type) + "\n" + rh.gs(R.string.notes_label) + ": " + (therapyEvent.note ?: "") + "\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(therapyEvent.timestamp) } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } private fun removeSelected() { - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { therapyEvent -> + selectedItems.forEach { _, therapyEvent -> uel.log( Action.CAREPORTAL_REMOVED, Sources.Treatments, therapyEvent.note, ValueWithUnit.Timestamp(therapyEvent.timestamp), @@ -295,9 +298,11 @@ class TreatmentsCareportalFragment : DaggerFragment() { { aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) } ) } - + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt index c4ac1aff5b..57e766dc54 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsExtendedBolusesFragment.kt @@ -2,9 +2,11 @@ package info.nightscout.androidaps.activities.fragments import android.annotation.SuppressLint import android.os.Bundle +import android.util.SparseArray import android.view.* import android.view.ActionMode import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -59,11 +61,10 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { @Inject lateinit var repository: AppRepository private var _binding: TreatmentsExtendedbolusFragmentBinding? = null - // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var removeActionMode: ActionMode? = null private var toolbar: Toolbar? = null @@ -149,13 +150,16 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { holder.binding.ratio.text = rh.gs(R.string.pump_basebasalrate, extendedBolus.rate) if (iob.iob != 0.0) holder.binding.iob.setTextColor(rh.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.insulin.currentTextColor) holder.binding.cbRemove.visibility = (extendedBolus.isValid && removeActionMode != null).toVisibility() - holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(extendedBolus) - } else { - selectedItems.remove(extendedBolus) + if (removeActionMode != null) { + holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, extendedBolus) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) + holder.binding.cbRemove.isChecked = selectedItems.get(position) != null } val nextTimestamp = if (extendedBolusList.size != position + 1) extendedBolusList[position + 1].timestamp else 0L holder.binding.delimiter.visibility = dateUtil.isSameDay(extendedBolus.timestamp, nextTimestamp).toVisibility() @@ -209,8 +213,8 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -221,7 +225,6 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -236,18 +239,19 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { + if (selectedItems.size() == 1) { + val bolus = selectedItems.valueAt(0) return rh.gs(R.string.extended_bolus) + "\n" + - "${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(selectedItems.first().timestamp)}" + "${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(bolus.timestamp)}" } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } private fun removeSelected() { - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { extendedBolus -> + selectedItems.forEach { _, extendedBolus -> uel.log( Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments, ValueWithUnit.Timestamp(extendedBolus.timestamp), @@ -260,7 +264,10 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() { { aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") }, { aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) }) } + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt index 38073e13ad..2922ead097 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsProfileSwitchFragment.kt @@ -2,9 +2,11 @@ package info.nightscout.androidaps.activities.fragments import android.graphics.Paint import android.os.Bundle +import android.util.SparseArray import android.view.* import android.view.ActionMode import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -61,17 +63,16 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { @Inject lateinit var uel: UserEntryLogger private var _binding: TreatmentsProfileswitchFragmentBinding? = null + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! private val disposable = CompositeDisposable() - private val millsToThePast = T.days(30).msecs() - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var removeActionMode: ActionMode? = null private var toolbar: Toolbar? = null - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = TreatmentsProfileswitchFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root @@ -198,13 +199,16 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { holder.binding.invalid.visibility = profileSwitch.isValid.not().toVisibility() holder.binding.duration.visibility = (profileSwitch.duration != 0L && profileSwitch.duration != null).toVisibility() holder.binding.cbRemove.visibility = (removeActionMode != null && profileSwitch is ProfileSealed.PS).toVisibility() - holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(profileSwitch) - } else { - selectedItems.remove(profileSwitch) + if (removeActionMode != null) { + holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, profileSwitch) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) + holder.binding.cbRemove.isChecked = selectedItems.get(position) != null } holder.binding.clone.visibility = (profileSwitch is ProfileSealed.PS).toVisibility() holder.binding.spacer.visibility = (profileSwitch is ProfileSealed.PS).toVisibility() @@ -314,8 +318,8 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -326,7 +330,6 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -341,18 +344,18 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { - val profileSwitch = selectedItems.first() + if (selectedItems.size() == 1) { + val profileSwitch = selectedItems.valueAt(0) return rh.gs(R.string.careportal_profileswitch) + ": " + profileSwitch.profileName + "\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.timestamp) } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } private fun removeSelected() { - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { profileSwitch -> + selectedItems.forEach { _, profileSwitch -> uel.log( Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName, ValueWithUnit.Timestamp(profileSwitch.timestamp) @@ -363,7 +366,10 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() { { aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) } ) } + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt index 846c1122e0..2144feb13e 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTempTargetFragment.kt @@ -2,8 +2,10 @@ package info.nightscout.androidaps.activities.fragments import android.annotation.SuppressLint import android.os.Bundle +import android.util.SparseArray import android.view.* import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -65,19 +67,17 @@ class TreatmentsTempTargetFragment : DaggerFragment() { @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository - private val disposable = CompositeDisposable() + private var _binding: TreatmentsTemptargetFragmentBinding? = null + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! + private val disposable = CompositeDisposable() private val millsToThePast = T.days(30).msecs() - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var toolbar: Toolbar? = null private var removeActionMode: ActionMode? = null - private var _binding: TreatmentsTemptargetFragmentBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = TreatmentsTemptargetFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root @@ -174,13 +174,16 @@ class TreatmentsTempTargetFragment : DaggerFragment() { holder.binding.ns.visibility = (tempTarget.interfaceIDs.nightscoutId != null).toVisibility() holder.binding.invalid.visibility = tempTarget.isValid.not().toVisibility() holder.binding.cbRemove.visibility = (tempTarget.isValid && removeActionMode != null).toVisibility() - holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(tempTarget) - } else { - selectedItems.remove(tempTarget) + if (removeActionMode != null) { + holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, tempTarget) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) + holder.binding.cbRemove.isChecked = selectedItems.get(position) != null } val sameDayPrevious = position > 0 && dateUtil.isSameDay(tempTarget.timestamp, tempTargetList[position - 1].timestamp) holder.binding.date.visibility = sameDayPrevious.not().toVisibility() @@ -211,10 +214,10 @@ class TreatmentsTempTargetFragment : DaggerFragment() { } private fun removeSelected() { - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { tempTarget -> + selectedItems.forEach { _, tempTarget -> uel.log( Action.TT_REMOVED, Sources.Treatments, ValueWithUnit.Timestamp(tempTarget.timestamp), @@ -228,8 +231,11 @@ class TreatmentsTempTargetFragment : DaggerFragment() { { aapsLogger.debug(LTag.DATABASE, "Removed temp target $tempTarget") }, { aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it) }) } + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -277,8 +283,8 @@ class TreatmentsTempTargetFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -289,7 +295,6 @@ class TreatmentsTempTargetFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -304,12 +309,12 @@ class TreatmentsTempTargetFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { - val tempTarget = selectedItems.first() + if (selectedItems.size() == 1) { + val tempTarget = selectedItems.valueAt(0) return "${rh.gs(R.string.careportal_temporarytarget)}: ${tempTarget.friendlyDescription(profileFunction.getUnits(), rh)}\n" + dateUtil.dateAndTimeString(tempTarget.timestamp) } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } } diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt index b24f062004..babd7f64c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt @@ -1,8 +1,11 @@ package info.nightscout.androidaps.activities.fragments import android.os.Bundle +import android.util.Log +import android.util.SparseArray import android.view.* import androidx.appcompat.widget.Toolbar +import androidx.core.util.forEach import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import dagger.android.support.DaggerFragment @@ -62,16 +65,15 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { @Inject lateinit var repository: AppRepository private var _binding: TreatmentsTempbasalsFragmentBinding? = null + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! private val millsToThePast = T.days(30).msecs() - private var selectedItems: MutableList = mutableListOf() + private var selectedItems: SparseArray = SparseArray() private var showInvalidated = false private var toolbar: Toolbar? = null private var removeActionMode: ActionMode? = null - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View = TreatmentsTempbasalsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root @@ -192,13 +194,16 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { holder.binding.superBolusFlag.visibility = (tempBasal.type == TemporaryBasal.Type.SUPERBOLUS).toVisibility() if (abs(iob.basaliob) > 0.01) holder.binding.iob.setTextColor(rh.gc(R.color.colorActive)) else holder.binding.iob.setTextColor(holder.binding.duration.currentTextColor) holder.binding.cbRemove.visibility = (tempBasal.isValid && removeActionMode != null).toVisibility() - holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> - if (value) { - selectedItems.add(tempBasal) - } else { - selectedItems.remove(tempBasal) + if (removeActionMode != null) { + holder.binding.cbRemove.setOnCheckedChangeListener { _, value -> + if (value) { + selectedItems.put(position, tempBasal) + } else { + selectedItems.remove(position) + } + removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size()) } - removeActionMode?.title = rh.gs(R.string.count_selected, selectedItems.size) + holder.binding.cbRemove.isChecked = selectedItems.get(position) != null } val nextTimestamp = if (tempBasalList.size != position + 1) tempBasalList[position + 1].timestamp else 0L holder.binding.delimiter.visibility = dateUtil.isSameDay(tempBasal.timestamp, nextTimestamp).toVisibility() @@ -252,8 +257,8 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean { mode.menuInflater.inflate(R.menu.menu_delete_selection, menu) - selectedItems = mutableListOf() - mode.title = rh.gs(R.string.count_selected, selectedItems.size) + selectedItems.clear() + mode.title = rh.gs(R.string.count_selected, selectedItems.size()) binding.recyclerview.adapter?.notifyDataSetChanged() return true } @@ -264,7 +269,6 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { return when (item.itemId) { R.id.remove_selected -> { removeSelected() - mode.finish() true } @@ -279,23 +283,22 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { } private fun getConfirmationText(): String { - if (selectedItems.size == 1) { - val tempBasal = selectedItems.first() + if (selectedItems.size() == 1) { + val tempBasal = selectedItems.valueAt(0) val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED val profile = profileFunction.getProfile(dateUtil.now()) if (profile != null) return "${if (isFakeExtended) rh.gs(R.string.extended_bolus) else rh.gs(R.string.tempbasal_label)}: ${tempBasal.toStringFull(profile, dateUtil)}\n" + "${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(tempBasal.timestamp)}" } - return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size) + return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size()) } private fun removeSelected() { - // TODO check if item should not be delete val profile = profileFunction.getProfile(dateUtil.now()) == null - if (selectedItems.size > 0) + if (selectedItems.size() > 0) activity?.let { activity -> OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable { - selectedItems.forEach { tempBasal -> + selectedItems.forEach {_, tempBasal -> var extendedBolus: ExtendedBolus? = null val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED if (isFakeExtended) { @@ -327,7 +330,10 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { { aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) }) } } + removeActionMode?.finish() }) } + else + removeActionMode?.finish() } }