From 228167820cb2cc0b7f6fa54f0ff5c54bafd628fd Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 11 Nov 2022 10:33:09 +0100 Subject: [PATCH] FillDialog -> ui --- .../androidaps/di/FragmentsModule.kt | 2 - .../androidaps/dialogs/FillDialog.kt | 229 ----------------- .../general/actions/ActionsFragment.kt | 4 +- .../wear/wearintegration/DataHandlerMobile.kt | 4 +- app/src/main/res/layout/actions_fragment.xml | 4 +- app/src/main/res/values/strings.xml | 10 - .../nightscout/androidaps/utils/Translator.kt | 4 +- .../userEntry/UserEntryPresentationHelper.kt | 2 +- ...pump_canula.xml => ic_cp_pump_cannula.xml} | 0 .../core-main/src/main/res/values/strings.xml | 6 +- .../java/info/nightscout/ui/di/UiModule.kt | 2 + .../info/nightscout/ui/dialogs/FillDialog.kt | 232 ++++++++++++++++++ .../src/main/res/layout/dialog_fill.xml | 10 +- ui/src/main/res/values/strings.xml | 15 +- 14 files changed, 266 insertions(+), 258 deletions(-) rename core/core-main/src/main/res/drawable/{ic_cp_pump_canula.xml => ic_cp_pump_cannula.xml} (100%) create mode 100644 ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt rename {app => ui}/src/main/res/layout/dialog_fill.xml (94%) diff --git a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt index 7e465d6248..acd0f1877e 100644 --- a/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/di/FragmentsModule.kt @@ -3,7 +3,6 @@ package info.nightscout.androidaps.di import dagger.Module import dagger.android.ContributesAndroidInjector import info.nightscout.androidaps.activities.MyPreferenceFragment -import info.nightscout.androidaps.dialogs.FillDialog import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.dialogs.LoopDialog import info.nightscout.androidaps.dialogs.NtpProgressDialog @@ -41,7 +40,6 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog - @ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog @ContributesAndroidInjector abstract fun contributesInsulinDialog(): InsulinDialog @ContributesAndroidInjector abstract fun contributesLoopDialog(): LoopDialog @ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): ObjectivesExamDialog diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index 88f887a40a..2e4bef4f6d 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -1,231 +1,2 @@ package info.nightscout.androidaps.dialogs -import android.content.Context -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import com.google.common.base.Joiner -import info.nightscout.androidaps.R -import info.nightscout.androidaps.databinding.DialogFillBinding -import info.nightscout.androidaps.extensions.formatColor -import info.nightscout.androidaps.interfaces.ActivePlugin -import info.nightscout.androidaps.interfaces.CommandQueue -import info.nightscout.androidaps.interfaces.Constraints -import info.nightscout.androidaps.logging.UserEntryLogger -import info.nightscout.androidaps.utils.DecimalFormatter -import info.nightscout.androidaps.utils.ToastUtils -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.protection.ProtectionCheck -import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.BOLUS -import info.nightscout.database.entities.TherapyEvent -import info.nightscout.database.entities.UserEntry.Action -import info.nightscout.database.entities.UserEntry.Sources -import info.nightscout.database.entities.ValueWithUnit -import info.nightscout.database.impl.AppRepository -import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyEventTransaction -import info.nightscout.interfaces.constraints.Constraint -import info.nightscout.interfaces.pump.DetailedBolusInfo -import info.nightscout.interfaces.queue.Callback -import info.nightscout.interfaces.ui.ActivityNames -import info.nightscout.interfaces.utils.HtmlHelper -import info.nightscout.rx.logging.LTag -import info.nightscout.shared.SafeParse -import info.nightscout.shared.interfaces.ResourceHelper -import io.reactivex.rxjava3.disposables.CompositeDisposable -import io.reactivex.rxjava3.kotlin.plusAssign -import java.util.LinkedList -import javax.inject.Inject -import kotlin.math.abs - -class FillDialog : DialogFragmentWithDate() { - - @Inject lateinit var constraintChecker: Constraints - @Inject lateinit var rh: ResourceHelper - @Inject lateinit var ctx: Context - @Inject lateinit var commandQueue: CommandQueue - @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var uel: UserEntryLogger - @Inject lateinit var repository: AppRepository - @Inject lateinit var protectionCheck: ProtectionCheck - @Inject lateinit var activityNames: ActivityNames - - private var queryingProtection = false - private val disposable = CompositeDisposable() - private var _binding: DialogFillBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - private val binding get() = _binding!! - - override fun onSaveInstanceState(savedInstanceState: Bundle) { - super.onSaveInstanceState(savedInstanceState) - savedInstanceState.putDouble("fill_insulin_amount", binding.fillInsulinamount.value) - } - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - onCreateViewGeneral() - _binding = DialogFillBinding.inflate(inflater, container, false) - return binding.root - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - val maxInsulin = constraintChecker.getMaxBolusAllowed().value() - val bolusStep = activePlugin.activePump.pumpDescription.bolusStep - binding.fillInsulinamount.setParams( - savedInstanceState?.getDouble("fill_insulin_amount") - ?: 0.0, 0.0, maxInsulin, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), true, binding.okcancel.ok - ) - val amount1 = sp.getDouble("fill_button1", 0.3) - if (amount1 > 0) { - binding.fillPresetButton1.visibility = View.VISIBLE - binding.fillPresetButton1.text = DecimalFormatter.toPumpSupportedBolus(amount1, activePlugin.activePump) // + "U"); - binding.fillPresetButton1.setOnClickListener { binding.fillInsulinamount.value = amount1 } - } else { - binding.fillPresetButton1.visibility = View.GONE - } - val amount2 = sp.getDouble("fill_button2", 0.0) - if (amount2 > 0) { - binding.fillPresetButton2.visibility = View.VISIBLE - binding.fillPresetButton2.text = DecimalFormatter.toPumpSupportedBolus(amount2, activePlugin.activePump) // + "U"); - binding.fillPresetButton2.setOnClickListener { binding.fillInsulinamount.value = amount2 } - } else { - binding.fillPresetButton2.visibility = View.GONE - } - val amount3 = sp.getDouble("fill_button3", 0.0) - if (amount3 > 0) { - binding.fillPresetButton3.visibility = View.VISIBLE - binding.fillPresetButton3.text = DecimalFormatter.toPumpSupportedBolus(amount3, activePlugin.activePump) // + "U"); - binding.fillPresetButton3.setOnClickListener { binding.fillInsulinamount.value = amount3 } - } else { - binding.fillPresetButton3.visibility = View.GONE - } - binding.fillLabel.labelFor = binding.fillInsulinamount.editTextId - } - - override fun onDestroyView() { - super.onDestroyView() - _binding = null - } - - override fun submit(): Boolean { - if (_binding == null) return false - val insulin = SafeParse.stringToDouble(binding.fillInsulinamount.text) - val actions: LinkedList = LinkedList() - - val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() - if (insulinAfterConstraints > 0) { - actions.add(rh.gs(R.string.fillwarning)) - actions.add("") - actions.add(rh.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, rh).formatColor(context, rh, R.attr.insulinButtonColor)) - if (abs(insulinAfterConstraints - insulin) > 0.01) - actions.add(rh.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(context, rh, R.attr.warningColor)) - } - val siteChange = binding.fillCatheterChange.isChecked - if (siteChange) - actions.add(rh.gs(R.string.record_pump_site_change).formatColor(context, rh, R.attr.actionsConfirmColor)) - val insulinChange = binding.fillCartridgeChange.isChecked - if (insulinChange) - actions.add(rh.gs(R.string.record_insulin_cartridge_change).formatColor(context, rh, R.attr.actionsConfirmColor)) - val notes: String = binding.notesLayout.notes.text.toString() - if (notes.isNotEmpty()) - actions.add(rh.gs(R.string.notes_label) + ": " + notes) - eventTime -= eventTime % 1000 - - if (eventTimeChanged) - actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime)) - - if (insulinAfterConstraints > 0 || binding.fillCatheterChange.isChecked || binding.fillCartridgeChange.isChecked) { - activity?.let { activity -> - OKDialog.showConfirmation(activity, rh.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { - if (insulinAfterConstraints > 0) { - uel.log(Action.PRIME_BOLUS, Sources.FillDialog, - notes, - ValueWithUnit.Insulin(insulinAfterConstraints)) - requestPrimeBolus(insulinAfterConstraints, notes) - } - if (siteChange) { - uel.log( - Action.SITE_CHANGE, Sources.FillDialog, - notes, - ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, - ValueWithUnit.TherapyEventType(TherapyEvent.Type.CANNULA_CHANGE) - ) - disposable += repository.runTransactionForResult( - InsertIfNewByTimestampTherapyEventTransaction( - timestamp = eventTime, - type = TherapyEvent.Type.CANNULA_CHANGE, - note = notes, - glucoseUnit = TherapyEvent.GlucoseUnit.MGDL - ) - ).subscribe( - { result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } }, - { aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) } - ) - } - if (insulinChange) { - // add a second for case of both checked - uel.log( - Action.RESERVOIR_CHANGE, Sources.FillDialog, - notes, - ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, - ValueWithUnit.TherapyEventType(TherapyEvent.Type.INSULIN_CHANGE) - ) - disposable += repository.runTransactionForResult( - InsertIfNewByTimestampTherapyEventTransaction( - timestamp = eventTime + 1000, - type = TherapyEvent.Type.INSULIN_CHANGE, - note = notes, - glucoseUnit = TherapyEvent.GlucoseUnit.MGDL - ) - ).subscribe( - { result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } }, - { aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) } - ) - } - }, null) - } - } else { - activity?.let { activity -> - OKDialog.show(activity, rh.gs(R.string.primefill), rh.gs(R.string.no_action_selected)) - } - } - dismiss() - return true - } - - private fun requestPrimeBolus(insulin: Double, notes: String) { - val detailedBolusInfo = DetailedBolusInfo() - detailedBolusInfo.insulin = insulin - detailedBolusInfo.context = context - detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.PRIMING - detailedBolusInfo.notes = notes - commandQueue.bolus(detailedBolusInfo, object : Callback() { - override fun run() { - if (!result.success) { - activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) - } - } - }) - } - - override fun onResume() { - super.onResume() - if (!queryingProtection) { - queryingProtection = true - activity?.let { activity -> - val cancelFail = { - queryingProtection = false - aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.simpleName}") - ToastUtils.warnToast(ctx, R.string.dialog_canceled) - dismiss() - } - protectionCheck.queryProtection(activity, BOLUS, { queryingProtection = false }, cancelFail, cancelFail) - } - } - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index 9226532c8c..f5ec1b556d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -13,8 +13,6 @@ import dagger.android.support.DaggerFragment import info.nightscout.androidaps.R import info.nightscout.androidaps.activities.HistoryBrowseActivity import info.nightscout.androidaps.databinding.ActionsFragmentBinding -import info.nightscout.ui.dialogs.ExtendedBolusDialog -import info.nightscout.androidaps.dialogs.FillDialog import info.nightscout.androidaps.dialogs.ProfileSwitchDialog import info.nightscout.androidaps.dialogs.TempBasalDialog import info.nightscout.androidaps.dialogs.TempTargetDialog @@ -56,6 +54,8 @@ import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.utils.DateUtil import info.nightscout.ui.activities.TDDStatsActivity import info.nightscout.ui.dialogs.CareDialog +import info.nightscout.ui.dialogs.ExtendedBolusDialog +import info.nightscout.ui.dialogs.FillDialog import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import javax.inject.Inject diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index c829b5f68d..6a52c89dac 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -540,7 +540,7 @@ class DataHandlerMobile @Inject constructor( else -> return } val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value() - var message = rh.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U" + var message = rh.gs(R.string.prime_fill) + ": " + insulinAfterConstraints + "U" if (insulinAfterConstraints - amount != 0.0) message += "\n" + rh.gs(R.string.constraint_applied) rxBus.send( EventMobileToWear( @@ -554,7 +554,7 @@ class DataHandlerMobile @Inject constructor( private fun handleFillPreCheck(command: EventData.ActionFillPreCheck) { val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(command.insulin)).value() - var message = rh.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U" + var message = rh.gs(R.string.prime_fill) + ": " + insulinAfterConstraints + "U" if (insulinAfterConstraints - command.insulin != 0.0) message += "\n" + rh.gs(R.string.constraint_applied) rxBus.send( EventMobileToWear( diff --git a/app/src/main/res/layout/actions_fragment.xml b/app/src/main/res/layout/actions_fragment.xml index 8c4fa406a7..8136b4ca1b 100644 --- a/app/src/main/res/layout/actions_fragment.xml +++ b/app/src/main/res/layout/actions_fragment.xml @@ -208,10 +208,10 @@ style="@style/GrayButton" android:layout_width="0dp" android:layout_height="wrap_content" - android:drawableTop="@drawable/ic_cp_pump_canula" + android:drawableTop="@drawable/ic_cp_pump_cannula" android:paddingStart="0dp" android:paddingEnd="0dp" - android:text="@string/primefill" + android:text="@string/prime_fill" android:textSize="11sp" app:layout_column="1" app:layout_columnWeight="1" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 55ec9f77f8..45eeaf7823 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -158,12 +158,6 @@ (DANGEROUS TO DISABLE) NS upload only NS upload only (disabled sync). Not effective on SGV unless a local source like xDrip+ is selected. Not effective on Profiles while NS-Profiles is used.\n!!! WARNING !!! Disabling this option may cause malfunctions and insulin overdose if any of your component (AAPS, NS, xDrip+) is wrong configured. Carefully watch if data displayed by AAPS match the pump state! Pump not initialized! - Prime/Fill - Please make sure the amount matches the specification of your infusion set! - Fill/Prime standard insulin amounts - Button 1 - Button 2 - Button 3 Units Range for Visualization High and low mark for the charts in Overview and Smartwatch @@ -358,7 +352,6 @@ Enable SMB when there is temp target active (eating soon, exercise) Enable SMB with high temp targets Enable SMB when there is high temp target active (exercise, above 100 mg/dl or 5.5 mmol/l) - Insulin Buttons show_calibration_button show_cgm_button @@ -422,8 +415,6 @@ max value in preferences hard limit openapsama_useautosens - Record pump site change - Record insulin cartridge change SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering SMB not allowed in open loop mode IobCobCalculator @@ -524,7 +515,6 @@ uamsmbmaxminutes 2h COB vs IOB - Bolus constraint applied: %1$.2f U to %2$.2f U !!!!! Slow carbs absorption detected: %2$d%% of time. Double check your calculation. COB can be overestimated thus more insulin could be given !!!!!]]> boluswizard_percentage Deliver this part of bolus wizard result [%] diff --git a/core/core-main/src/main/java/info/nightscout/androidaps/utils/Translator.kt b/core/core-main/src/main/java/info/nightscout/androidaps/utils/Translator.kt index 0a8ee44dde..79ebf5557d 100644 --- a/core/core-main/src/main/java/info/nightscout/androidaps/utils/Translator.kt +++ b/core/core-main/src/main/java/info/nightscout/androidaps/utils/Translator.kt @@ -137,12 +137,12 @@ class Translator @Inject internal constructor( TherapyEvent.Type.NOTE -> rh.gs(R.string.careportal_note) TherapyEvent.Type.QUESTION -> rh.gs(R.string.careportal_question) TherapyEvent.Type.EXERCISE -> rh.gs(R.string.careportal_exercise) - TherapyEvent.Type.CANNULA_CHANGE -> rh.gs(R.string.careportal_pumpsitechange) + TherapyEvent.Type.CANNULA_CHANGE -> rh.gs(R.string.careportal_pump_site_change) TherapyEvent.Type.PUMP_BATTERY_CHANGE -> rh.gs(R.string.careportal_pumpbatterychange) TherapyEvent.Type.SENSOR_STARTED -> rh.gs(R.string.careportal_cgmsensorstart) TherapyEvent.Type.SENSOR_STOPPED -> rh.gs(R.string.careportal_cgm_sensor_stop) TherapyEvent.Type.SENSOR_CHANGE -> rh.gs(R.string.careportal_cgmsensorinsert) - TherapyEvent.Type.INSULIN_CHANGE -> rh.gs(R.string.careportal_insulincartridgechange) + TherapyEvent.Type.INSULIN_CHANGE -> rh.gs(R.string.careportal_insulin_cartridge_change) TherapyEvent.Type.DAD_ALERT -> rh.gs(R.string.careportal_dad_alert) TherapyEvent.Type.TEMPORARY_BASAL_START -> rh.gs(R.string.careportal_tempbasalstart) TherapyEvent.Type.TEMPORARY_BASAL_END -> rh.gs(R.string.careportal_tempbasalend) diff --git a/core/core-main/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt b/core/core-main/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt index 2de85ac78d..8452ad84a8 100644 --- a/core/core-main/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt +++ b/core/core-main/src/main/java/info/nightscout/androidaps/utils/userEntry/UserEntryPresentationHelper.kt @@ -53,7 +53,7 @@ class UserEntryPresentationHelper @Inject constructor( Sources.LoopDialog -> R.drawable.ic_loop_closed Sources.TempBasalDialog -> R.drawable.ic_actions_starttempbasal Sources.CalibrationDialog -> R.drawable.ic_calibration - Sources.FillDialog -> R.drawable.ic_cp_pump_canula + Sources.FillDialog -> R.drawable.ic_cp_pump_cannula Sources.BgCheck -> R.drawable.ic_cp_bgcheck Sources.SensorInsert -> R.drawable.ic_cp_cgm_insert Sources.BatteryChange -> R.drawable.ic_cp_pump_battery diff --git a/core/core-main/src/main/res/drawable/ic_cp_pump_canula.xml b/core/core-main/src/main/res/drawable/ic_cp_pump_cannula.xml similarity index 100% rename from core/core-main/src/main/res/drawable/ic_cp_pump_canula.xml rename to core/core-main/src/main/res/drawable/ic_cp_pump_cannula.xml diff --git a/core/core-main/src/main/res/values/strings.xml b/core/core-main/src/main/res/values/strings.xml index 109022b62d..aa66f3b196 100644 --- a/core/core-main/src/main/res/values/strings.xml +++ b/core/core-main/src/main/res/values/strings.xml @@ -254,6 +254,8 @@ INVALID Login Upload now + Prime/Fill + Insulin Limiting max basal rate to %1$.2f U/h because of %2$s @@ -320,12 +322,12 @@ Note : %1$s Question : %1$s Exercise : %1$s - Pump Site Change + Pump Site Change CGM Sensor Insert CGM Sensor Start CGM Sensor Stop D.A.D. Alert - Insulin Cartridge Change + Insulin Cartridge Change Profile switch Snack Bolus Meal Bolus diff --git a/ui/src/main/java/info/nightscout/ui/di/UiModule.kt b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt index d0573b986f..f58bc19144 100644 --- a/ui/src/main/java/info/nightscout/ui/di/UiModule.kt +++ b/ui/src/main/java/info/nightscout/ui/di/UiModule.kt @@ -20,6 +20,7 @@ import info.nightscout.ui.dialogs.CalibrationDialog import info.nightscout.ui.dialogs.CarbsDialog import info.nightscout.ui.dialogs.CareDialog import info.nightscout.ui.dialogs.ExtendedBolusDialog +import info.nightscout.ui.dialogs.FillDialog import info.nightscout.ui.dialogs.ProfileViewerDialog import info.nightscout.ui.dialogs.WizardInfoDialog @@ -33,6 +34,7 @@ abstract class UiModule { @ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog @ContributesAndroidInjector abstract fun contributesProfileViewerDialog(): ProfileViewerDialog @ContributesAndroidInjector abstract fun contributesExtendedBolusDialog(): ExtendedBolusDialog + @ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog @ContributesAndroidInjector abstract fun contributesTDDStatsActivity(): TDDStatsActivity @ContributesAndroidInjector abstract fun contributeBolusProgressHelperActivity(): BolusProgressHelperActivity diff --git a/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt b/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt new file mode 100644 index 0000000000..2f5d388375 --- /dev/null +++ b/ui/src/main/java/info/nightscout/ui/dialogs/FillDialog.kt @@ -0,0 +1,232 @@ +package info.nightscout.ui.dialogs + +import android.content.Context +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.google.common.base.Joiner +import info.nightscout.androidaps.dialogs.DialogFragmentWithDate +import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.interfaces.CommandQueue +import info.nightscout.androidaps.interfaces.Constraints +import info.nightscout.androidaps.logging.UserEntryLogger +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.protection.ProtectionCheck +import info.nightscout.database.entities.TherapyEvent +import info.nightscout.database.entities.UserEntry +import info.nightscout.database.entities.ValueWithUnit +import info.nightscout.database.impl.AppRepository +import info.nightscout.database.impl.transactions.InsertIfNewByTimestampTherapyEventTransaction +import info.nightscout.interfaces.constraints.Constraint +import info.nightscout.interfaces.pump.DetailedBolusInfo +import info.nightscout.interfaces.queue.Callback +import info.nightscout.interfaces.ui.ActivityNames +import info.nightscout.interfaces.utils.HtmlHelper +import info.nightscout.rx.logging.LTag +import info.nightscout.shared.SafeParse +import info.nightscout.shared.interfaces.ResourceHelper +import info.nightscout.ui.R +import info.nightscout.ui.databinding.DialogFillBinding +import io.reactivex.rxjava3.disposables.CompositeDisposable +import io.reactivex.rxjava3.kotlin.plusAssign +import java.util.LinkedList +import javax.inject.Inject +import kotlin.math.abs + +class FillDialog : DialogFragmentWithDate() { + + @Inject lateinit var constraintChecker: Constraints + @Inject lateinit var rh: ResourceHelper + @Inject lateinit var ctx: Context + @Inject lateinit var commandQueue: CommandQueue + @Inject lateinit var activePlugin: ActivePlugin + @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var repository: AppRepository + @Inject lateinit var protectionCheck: ProtectionCheck + @Inject lateinit var activityNames: ActivityNames + + private var queryingProtection = false + private val disposable = CompositeDisposable() + private var _binding: DialogFillBinding? = null + + // This property is only valid between onCreateView and onDestroyView. + private val binding get() = _binding!! + + override fun onSaveInstanceState(savedInstanceState: Bundle) { + super.onSaveInstanceState(savedInstanceState) + savedInstanceState.putDouble("fill_insulin_amount", binding.fillInsulinAmount.value) + } + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + onCreateViewGeneral() + _binding = DialogFillBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val maxInsulin = constraintChecker.getMaxBolusAllowed().value() + val bolusStep = activePlugin.activePump.pumpDescription.bolusStep + binding.fillInsulinAmount.setParams( + savedInstanceState?.getDouble("fill_insulin_amount") + ?: 0.0, 0.0, maxInsulin, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), true, binding.okcancel.ok + ) + val amount1 = sp.getDouble("fill_button1", 0.3) + if (amount1 > 0) { + binding.fillPresetButton1.visibility = View.VISIBLE + binding.fillPresetButton1.text = DecimalFormatter.toPumpSupportedBolus(amount1, activePlugin.activePump) // + "U"); + binding.fillPresetButton1.setOnClickListener { binding.fillInsulinAmount.value = amount1 } + } else { + binding.fillPresetButton1.visibility = View.GONE + } + val amount2 = sp.getDouble("fill_button2", 0.0) + if (amount2 > 0) { + binding.fillPresetButton2.visibility = View.VISIBLE + binding.fillPresetButton2.text = DecimalFormatter.toPumpSupportedBolus(amount2, activePlugin.activePump) // + "U"); + binding.fillPresetButton2.setOnClickListener { binding.fillInsulinAmount.value = amount2 } + } else { + binding.fillPresetButton2.visibility = View.GONE + } + val amount3 = sp.getDouble("fill_button3", 0.0) + if (amount3 > 0) { + binding.fillPresetButton3.visibility = View.VISIBLE + binding.fillPresetButton3.text = DecimalFormatter.toPumpSupportedBolus(amount3, activePlugin.activePump) // + "U"); + binding.fillPresetButton3.setOnClickListener { binding.fillInsulinAmount.value = amount3 } + } else { + binding.fillPresetButton3.visibility = View.GONE + } + binding.fillLabel.labelFor = binding.fillInsulinAmount.editTextId + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + override fun submit(): Boolean { + if (_binding == null) return false + val insulin = SafeParse.stringToDouble(binding.fillInsulinAmount.text) + val actions: LinkedList = LinkedList() + + val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value() + if (insulinAfterConstraints > 0) { + actions.add(rh.gs(R.string.fillwarning)) + actions.add("") + actions.add(rh.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, rh).formatColor(context, rh, R.attr.insulinButtonColor)) + if (abs(insulinAfterConstraints - insulin) > 0.01) + actions.add(rh.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(context, rh, R.attr.warningColor)) + } + val siteChange = binding.fillCatheterChange.isChecked + if (siteChange) + actions.add(rh.gs(R.string.record_pump_site_change).formatColor(context, rh, R.attr.actionsConfirmColor)) + val insulinChange = binding.fillCartridgeChange.isChecked + if (insulinChange) + actions.add(rh.gs(R.string.record_insulin_cartridge_change).formatColor(context, rh, R.attr.actionsConfirmColor)) + val notes: String = binding.notesLayout.notes.text.toString() + if (notes.isNotEmpty()) + actions.add(rh.gs(R.string.notes_label) + ": " + notes) + eventTime -= eventTime % 1000 + + if (eventTimeChanged) + actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime)) + + if (insulinAfterConstraints > 0 || binding.fillCatheterChange.isChecked || binding.fillCartridgeChange.isChecked) { + activity?.let { activity -> + OKDialog.showConfirmation(activity, rh.gs(R.string.prime_fill), HtmlHelper.fromHtml(Joiner.on("
").join(actions)), { + if (insulinAfterConstraints > 0) { + uel.log( + UserEntry.Action.PRIME_BOLUS, UserEntry.Sources.FillDialog, + notes, + ValueWithUnit.Insulin(insulinAfterConstraints) + ) + requestPrimeBolus(insulinAfterConstraints, notes) + } + if (siteChange) { + uel.log( + UserEntry.Action.SITE_CHANGE, UserEntry.Sources.FillDialog, + notes, + ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, + ValueWithUnit.TherapyEventType(TherapyEvent.Type.CANNULA_CHANGE) + ) + disposable += repository.runTransactionForResult( + InsertIfNewByTimestampTherapyEventTransaction( + timestamp = eventTime, + type = TherapyEvent.Type.CANNULA_CHANGE, + note = notes, + glucoseUnit = TherapyEvent.GlucoseUnit.MGDL + ) + ).subscribe( + { result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } }, + { aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) } + ) + } + if (insulinChange) { + // add a second for case of both checked + uel.log( + UserEntry.Action.RESERVOIR_CHANGE, UserEntry.Sources.FillDialog, + notes, + ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, + ValueWithUnit.TherapyEventType(TherapyEvent.Type.INSULIN_CHANGE) + ) + disposable += repository.runTransactionForResult( + InsertIfNewByTimestampTherapyEventTransaction( + timestamp = eventTime + 1000, + type = TherapyEvent.Type.INSULIN_CHANGE, + note = notes, + glucoseUnit = TherapyEvent.GlucoseUnit.MGDL + ) + ).subscribe( + { result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } }, + { aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) } + ) + } + }, null) + } + } else { + activity?.let { activity -> + OKDialog.show(activity, rh.gs(R.string.prime_fill), rh.gs(R.string.no_action_selected)) + } + } + dismiss() + return true + } + + private fun requestPrimeBolus(insulin: Double, notes: String) { + val detailedBolusInfo = DetailedBolusInfo() + detailedBolusInfo.insulin = insulin + detailedBolusInfo.context = context + detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.PRIMING + detailedBolusInfo.notes = notes + commandQueue.bolus(detailedBolusInfo, object : Callback() { + override fun run() { + if (!result.success) { + activityNames.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) + } + } + }) + } + + override fun onResume() { + super.onResume() + if (!queryingProtection) { + queryingProtection = true + activity?.let { activity -> + val cancelFail = { + queryingProtection = false + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.simpleName}") + ToastUtils.warnToast(ctx, R.string.dialog_canceled) + dismiss() + } + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, { queryingProtection = false }, cancelFail, cancelFail) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_fill.xml b/ui/src/main/res/layout/dialog_fill.xml similarity index 94% rename from app/src/main/res/layout/dialog_fill.xml rename to ui/src/main/res/layout/dialog_fill.xml index 0bfd8f9749..d0cc7ce813 100644 --- a/app/src/main/res/layout/dialog_fill.xml +++ b/ui/src/main/res/layout/dialog_fill.xml @@ -23,7 +23,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:importantForAccessibility="no" - app:srcCompat="@drawable/ic_cp_pump_canula" /> + app:srcCompat="@drawable/ic_cp_pump_cannula" /> @@ -56,13 +56,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="5dp" - android:text="@string/careportal_pumpsitechange" /> + android:text="@string/careportal_pump_site_change" /> + android:text="@string/careportal_insulin_cartridge_change" /> @@ -82,7 +82,7 @@ android:textStyle="bold" /> Most common profile: Note: Only data visible on this screen will be anonymously uploaded. ID is assigned to this installation of AAPS. You can submit data again if your main profile get changed but let it running at least for a week to make result visible in time in range. Your help is appreciated. - + + + Bolus constraint applied: %1$.2f U to %2$.2f U + Glucose type Other Meter @@ -46,6 +49,16 @@ Superbolus Total + + Please make sure the amount matches the specification of your infusion set! + Fill/Prime standard insulin amounts + Button 1 + Button 2 + Button 3 + Record pump site change + Record insulin cartridge change + + No records available Calc