Merge pull request #1362 from Andries-Smit/feat/toolbar-treatment
Feature toolbar with options menu in Treatments
This commit is contained in:
commit
c0dbe41899
34 changed files with 1359 additions and 791 deletions
|
@ -1,13 +1,13 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentTransaction
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.fragments.*
|
||||
import info.nightscout.androidaps.databinding.TreatmentsFragmentBinding
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import javax.inject.Inject
|
||||
|
@ -23,40 +23,60 @@ class TreatmentsActivity : NoSplashAppCompatActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
binding = TreatmentsFragmentBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
//binding.tempBasals.visibility = buildHelper.isEngineeringMode().toVisibility()
|
||||
//binding.extendedBoluses.visibility = (buildHelper.isEngineeringMode() && !activePlugin.activePump.isFakingTempsByExtendedBoluses).toVisibility()
|
||||
|
||||
binding.treatments.setOnClickListener {
|
||||
setFragment(TreatmentsBolusCarbsFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.carbs_and_bolus)
|
||||
}
|
||||
binding.extendedBoluses.setOnClickListener {
|
||||
setFragment(TreatmentsExtendedBolusesFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.extended_bolus)
|
||||
}
|
||||
binding.tempBasals.setOnClickListener {
|
||||
setFragment(TreatmentsTemporaryBasalsFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.tempbasal_label)
|
||||
}
|
||||
binding.tempTargets.setOnClickListener {
|
||||
setFragment(TreatmentsTempTargetFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.tempt_targets)
|
||||
}
|
||||
binding.profileSwitches.setOnClickListener {
|
||||
setFragment(TreatmentsProfileSwitchFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.profile_changes)
|
||||
}
|
||||
binding.careportal.setOnClickListener {
|
||||
setFragment(TreatmentsCareportalFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.careportal)
|
||||
}
|
||||
binding.userentry.setOnClickListener {
|
||||
setFragment(TreatmentsUserEntryFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
supportActionBar?.title = rh.gs(R.string.user_action)
|
||||
}
|
||||
setFragment(TreatmentsBolusCarbsFragment())
|
||||
setBackgroundColorOnSelected(binding.treatments)
|
||||
setSupportActionBar(binding.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.title = rh.gs(R.string.carbs_and_bolus)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
android.R.id.home -> {
|
||||
finish()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun setFragment(selectedFragment: Fragment) {
|
||||
|
|
|
@ -3,9 +3,13 @@ package info.nightscout.androidaps.activities.fragments
|
|||
import android.annotation.SuppressLint
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
@ -67,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,
|
||||
|
@ -74,14 +82,12 @@ 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: SparseArray<MealLink> = 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 =
|
||||
TreatmentsBolusCarbsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
@ -89,92 +95,10 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
@SuppressLint("CheckResult")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllBolusCalculatorResults()
|
||||
repository.deleteAllBoluses()
|
||||
repository.deleteAllCarbs()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.deleteFutureTreatments.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), rh.gs(R.string.deletefuturetreatments) + "?", Runnable {
|
||||
uel.log(Action.DELETE_FUTURE_TREATMENTS, Sources.Treatments)
|
||||
repository
|
||||
.getBolusesDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolus ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
repository
|
||||
.getCarbsDataFromTimeNotExpanded(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { carb ->
|
||||
if (carb.duration == 0L)
|
||||
disposable += repository.runTransactionForResult(InvalidateCarbsTransaction(carb.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
else {
|
||||
disposable += repository.runTransactionForResult(CutCarbsTransaction(carb.id, dateUtil.now()))
|
||||
.subscribe(
|
||||
{ result ->
|
||||
result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated (cut end) carbs $it") }
|
||||
},
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
repository
|
||||
.getBolusCalculatorResultsDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolusCalc ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusCalculatorResultTransaction(bolusCalc.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolusCalculatorResult $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolusCalculatorResult", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.deleteFutureTreatments.visibility = View.GONE
|
||||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
private fun bolusMealLinksWithInvalid(now: Long) = repository
|
||||
|
@ -204,8 +128,9 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += carbsMealLinksWithInvalid(now)
|
||||
disposable +=
|
||||
if (showInvalidated)
|
||||
carbsMealLinksWithInvalid(now)
|
||||
.zipWith(bolusMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
|
@ -217,10 +142,9 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
else
|
||||
disposable += carbsMealLinks(now)
|
||||
carbsMealLinks(now)
|
||||
.zipWith(bolusMealLinks(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinks(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
|
@ -232,7 +156,6 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -267,13 +190,14 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun timestamp(ml: MealLink): Long = ml.bolusCalculatorResult?.let { it.timestamp } ?: ml.bolus?.let { it.timestamp } ?: ml.carbs?.let { it.timestamp } ?: 0L
|
||||
private fun timestamp(ml: MealLink): Long = ml.bolusCalculatorResult?.timestamp ?: ml.bolus?.timestamp ?: ml.carbs?.timestamp ?: 0L
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(var mealLinks: List<MealLink>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
|
||||
inner class RecyclerViewAdapter internal constructor(private var mealLinks: List<MealLink>) : RecyclerView.Adapter<RecyclerViewAdapter.MealLinkLoadedViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): MealLinkLoadedViewHolder =
|
||||
MealLinkLoadedViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_bolus_carbs_item, viewGroup, false))
|
||||
|
@ -287,13 +211,13 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
holder.binding.date.text = dateUtil.dateString(timestamp(ml))
|
||||
|
||||
// Metadata
|
||||
holder.binding.metadataLayout.visibility = (ml.bolusCalculatorResult != null && (ml.bolusCalculatorResult.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.metadataLayout.visibility = (ml.bolusCalculatorResult != null && (ml.bolusCalculatorResult.isValid || showInvalidated)).toVisibility()
|
||||
ml.bolusCalculatorResult?.let { bolusCalculatorResult ->
|
||||
holder.binding.calcTime.text = dateUtil.timeString(bolusCalculatorResult.timestamp)
|
||||
}
|
||||
|
||||
// Bolus
|
||||
holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus.isValid || showInvalidated)).toVisibility()
|
||||
ml.bolus?.let { bolus ->
|
||||
holder.binding.bolusTime.text = dateUtil.timeString(bolus.timestamp)
|
||||
holder.binding.insulin.text = rh.gs(R.string.formatinsulinunits, bolus.amount)
|
||||
|
@ -321,7 +245,7 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
// Carbs
|
||||
holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs.isValid || showInvalidated)).toVisibility()
|
||||
ml.carbs?.let { carbs ->
|
||||
holder.binding.carbsTime.text = dateUtil.timeString(carbs.timestamp)
|
||||
holder.binding.carbs.text = rh.gs(R.string.format_carbs, carbs.amount.toInt())
|
||||
|
@ -330,19 +254,28 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
holder.binding.carbsPump.visibility = (carbs.interfaceIDs.pumpId != null).toVisibility()
|
||||
holder.binding.carbsInvalid.visibility = carbs.isValid.not().toVisibility()
|
||||
}
|
||||
|
||||
holder.binding.bolusRemove.visibility = (ml.bolus?.isValid == true).toVisibility()
|
||||
holder.binding.carbsRemove.visibility = (ml.carbs?.isValid == true).toVisibility()
|
||||
holder.binding.bolusRemove.tag = ml
|
||||
holder.binding.carbsRemove.tag = ml
|
||||
holder.binding.cbBolusRemove.visibility = (ml.bolus?.isValid == true && removeActionMode != null).toVisibility()
|
||||
holder.binding.cbCarbsRemove.visibility = (ml.carbs?.isValid == true && removeActionMode != null).toVisibility()
|
||||
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()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mealLinks.size
|
||||
}
|
||||
override fun getItemCount() = mealLinks.size
|
||||
|
||||
inner class MealLinkLoadedViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
|
@ -359,35 +292,199 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
binding.calculation.paintFlags = binding.calculation.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.bolusRemove.setOnClickListener { ml ->
|
||||
val bolus = (ml.tag as MealLink?)?.bolus ?: return@setOnClickListener
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_carbs_bolus, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_insulin, false) || !sp.getBoolean(R.string.key_ns_receive_carbs, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
val hasItems = (binding.recyclerview.adapter?.itemCount ?: 0) > 0
|
||||
menu.findItem(R.id.nav_delete_future)?.isVisible = hasItems
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_delete_future -> {
|
||||
deleteFutureTreatments()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.configbuilder_insulin) + ": " +
|
||||
rh.gs(R.string.formatinsulinunits, bolus.amount) + "\n" +
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllBolusCalculatorResults()
|
||||
repository.deleteAllBoluses()
|
||||
repository.deleteAllCarbs()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteFutureTreatments() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), rh.gs(R.string.deletefuturetreatments) + "?", Runnable {
|
||||
uel.log(Action.DELETE_FUTURE_TREATMENTS, Sources.Treatments)
|
||||
disposable += repository
|
||||
.getBolusesDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolus ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
disposable += repository
|
||||
.getCarbsDataFromTimeNotExpanded(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { carb ->
|
||||
if (carb.duration == 0L)
|
||||
disposable += repository.runTransactionForResult(InvalidateCarbsTransaction(carb.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
else {
|
||||
disposable += repository.runTransactionForResult(CutCarbsTransaction(carb.id, dateUtil.now()))
|
||||
.subscribe(
|
||||
{ result ->
|
||||
result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated (cut end) carbs $it") }
|
||||
},
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
disposable += repository
|
||||
.getBolusCalculatorResultsDataFromTime(dateUtil.now(), false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
list.forEach { bolusCalc ->
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusCalculatorResultTransaction(bolusCalc.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolusCalculatorResult $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolusCalculatorResult", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
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" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(bolus.timestamp)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
val carbs = mealLink.carbs
|
||||
if (carbs != null)
|
||||
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())
|
||||
}
|
||||
|
||||
fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach {key, ml ->
|
||||
ml.bolus?.let { bolus ->
|
||||
uel.log(
|
||||
Action.BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(bolus.timestamp),
|
||||
ValueWithUnit.Insulin(bolus.amount)
|
||||
//ValueWithUnit.Gram(mealLinkLoaded.carbs.toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateBolusTransaction(bolus.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating bolus", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.bolusRemove.paintFlags = binding.bolusRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.carbsRemove.setOnClickListener { ml ->
|
||||
val carb = (ml.tag as MealLink?)?.carbs ?: return@setOnClickListener
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.carbs) + ": " +
|
||||
rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carb.amount.toInt()) + "\n" +
|
||||
rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(carb.timestamp)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
ml.carbs?.let { carb ->
|
||||
uel.log(
|
||||
Action.CARBS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(carb.timestamp),
|
||||
|
@ -398,11 +495,12 @@ class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
|||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating carbs", it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.carbsRemove.paintFlags = binding.carbsRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
@ -57,24 +58,30 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
|
||||
private var _binding: TreatmentsCareportalFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// 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: SparseArray<TherapyEvent> = SparseArray()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsCareportalFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
}
|
||||
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.refresheventsfromnightscout) + " ?", Runnable {
|
||||
uel.log(Action.CAREPORTAL_NS_REFRESH, Sources.Treatments)
|
||||
|
@ -88,30 +95,24 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
})
|
||||
}
|
||||
}
|
||||
binding.removeAndroidapsStartedEvents.setOnClickListener {
|
||||
|
||||
private fun removeStartedEvents() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal), rh.gs(R.string.careportal_removestartedevents), Runnable {
|
||||
uel.log(Action.RESTART_EVENTS_REMOVED, Sources.Treatments)
|
||||
repository.runTransactionForResult(InvalidateAAPSStartedTherapyEventTransaction(rh.gs(R.string.androidaps_start)))
|
||||
disposable += repository.runTransactionForResult(InvalidateAAPSStartedTherapyEventTransaction(rh.gs(R.string.androidaps_start)))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
disposable +=
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
repository
|
||||
.getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -148,6 +149,7 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -170,42 +172,137 @@ class TreatmentsCareportalFragment : DaggerFragment() {
|
|||
holder.binding.duration.text = if (therapyEvent.duration == 0L) "" else dateUtil.niceTimeScalar(therapyEvent.duration, rh)
|
||||
holder.binding.note.text = therapyEvent.note
|
||||
holder.binding.type.text = translator.translate(therapyEvent.type)
|
||||
holder.binding.remove.tag = therapyEvent
|
||||
holder.binding.cbRemove.visibility = (therapyEvent.isValid && removeActionMode != null).toVisibility()
|
||||
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())
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return therapyList.size
|
||||
}
|
||||
override fun getItemCount() = therapyList.size
|
||||
|
||||
inner class TherapyEventsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = TreatmentsCareportalItemBinding.bind(view)
|
||||
}
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val therapyEvent = v.tag as TherapyEvent
|
||||
activity?.let { activity ->
|
||||
val text = rh.gs(R.string.eventtype) + ": " + translator.translate(therapyEvent.type) + "\n" +
|
||||
rh.gs(R.string.notes_label) + ": " + (therapyEvent.note
|
||||
?: "") + "\n" +
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_careportal, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_therapy_events, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_remove_started_events -> {
|
||||
removeStartedEvents()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
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)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), text, Runnable {
|
||||
uel.log(Action.CAREPORTAL_REMOVED, Sources.Treatments, therapyEvent.note ,
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size())
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { _, therapyEvent ->
|
||||
uel.log(
|
||||
Action.CAREPORTAL_REMOVED, Sources.Treatments, therapyEvent.note,
|
||||
ValueWithUnit.Timestamp(therapyEvent.timestamp),
|
||||
ValueWithUnit.TherapyEventType(therapyEvent.type))
|
||||
ValueWithUnit.TherapyEventType(therapyEvent.type)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTherapyEventTransaction(therapyEvent.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating therapy event", it) }
|
||||
)
|
||||
}, null)
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
@ -27,16 +27,17 @@ import info.nightscout.androidaps.extensions.toVisibility
|
|||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment.RecyclerViewAdapter.ExtendedBolusesViewHolder
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
@ -60,23 +61,27 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private var _binding: TreatmentsExtendedbolusFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View =
|
||||
private var selectedItems: SparseArray<ExtendedBolus> = 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 =
|
||||
TreatmentsExtendedbolusFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += if (showInvalidated)
|
||||
repository
|
||||
.getExtendedBolusDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -109,6 +114,7 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -143,41 +149,125 @@ class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
|||
holder.binding.iob.text = rh.gs(R.string.formatinsulinunits, iob.iob)
|
||||
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.remove.tag = extendedBolus
|
||||
holder.binding.cbRemove.visibility = (extendedBolus.isValid && removeActionMode != null).toVisibility()
|
||||
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())
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = extendedBolusList.size
|
||||
override fun getItemCount() = extendedBolusList.size
|
||||
|
||||
inner class ExtendedBolusesViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsExtendedbolusItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val extendedBolus = v.tag as ExtendedBolus
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${rh.gs(R.string.extended_bolus)}
|
||||
${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(extendedBolus.timestamp)}
|
||||
""".trimIndent(), { _: DialogInterface, _: Int ->
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_extended_bolus, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
if (selectedItems.size() == 1) {
|
||||
val bolus = selectedItems.valueAt(0)
|
||||
return rh.gs(R.string.extended_bolus) + "\n" +
|
||||
"${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(bolus.timestamp)}"
|
||||
}
|
||||
return rh.gs(R.string.confirm_remove_multiple_items, selectedItems.size())
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { _, extendedBolus ->
|
||||
uel.log(
|
||||
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt()))
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
}
|
|
@ -2,9 +2,11 @@ package info.nightscout.androidaps.activities.fragments
|
|||
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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,24 +63,29 @@ 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: SparseArray<ProfileSealed> = 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
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
|
@ -101,11 +108,6 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()) binding.refreshFromNightscout.visibility = View.GONE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
private fun profileSwitchWithInvalid(now: Long) = repository
|
||||
.getProfileSwitchDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
|
@ -126,8 +128,9 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += profileSwitchWithInvalid(now)
|
||||
disposable +=
|
||||
if (showInvalidated)
|
||||
profileSwitchWithInvalid(now)
|
||||
.zipWith(effectiveProfileSwitchWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -135,14 +138,13 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
else
|
||||
disposable += profileSwitches(now)
|
||||
profileSwitches(now)
|
||||
.zipWith(effectiveProfileSwitches(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -168,6 +170,7 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -186,16 +189,27 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
holder.binding.date.text = dateUtil.dateString(profileSwitch.timestamp)
|
||||
holder.binding.time.text = dateUtil.timeString(profileSwitch.timestamp)
|
||||
holder.binding.duration.text = rh.gs(R.string.format_mins, T.msecs(profileSwitch.duration ?: 0L).mins())
|
||||
holder.binding.name.text = if (profileSwitch is ProfileSealed.PS) profileSwitch.value.getCustomizedName() else if (profileSwitch is ProfileSealed.EPS) profileSwitch.value.originalCustomizedName else ""
|
||||
holder.binding.name.text = if (profileSwitch is ProfileSealed.PS) profileSwitch.value.getCustomizedName()
|
||||
else if (profileSwitch is ProfileSealed.EPS) profileSwitch.value.originalCustomizedName else ""
|
||||
if (profileSwitch.isInProgress(dateUtil)) holder.binding.date.setTextColor(rh.gc(R.color.colorActive))
|
||||
else holder.binding.date.setTextColor(holder.binding.duration.currentTextColor)
|
||||
holder.binding.remove.tag = profileSwitch
|
||||
holder.binding.clone.tag = profileSwitch
|
||||
holder.binding.name.tag = profileSwitch
|
||||
holder.binding.date.tag = profileSwitch
|
||||
holder.binding.invalid.visibility = profileSwitch.isValid.not().toVisibility()
|
||||
holder.binding.duration.visibility = (profileSwitch.duration != 0L && profileSwitch.duration != null).toVisibility()
|
||||
holder.binding.remove.visibility = (profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
holder.binding.cbRemove.visibility = (removeActionMode != null && profileSwitch is ProfileSealed.PS).toVisibility()
|
||||
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())
|
||||
}
|
||||
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()
|
||||
holder.binding.root.setBackgroundColor(rh.gc(if (profileSwitch is ProfileSealed.PS) R.color.defaultbackground else R.color.list_delimiter))
|
||||
|
@ -203,47 +217,39 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
holder.binding.delimiter.visibility = dateUtil.isSameDay(profileSwitch.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return profileSwitchList.size
|
||||
}
|
||||
override fun getItemCount() = profileSwitchList.size
|
||||
|
||||
inner class ProfileSwitchViewHolder internal constructor(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsProfileswitchItemBinding.bind(itemView)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { view ->
|
||||
val profileSwitch = view.tag as ProfileSealed.PS
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord),
|
||||
rh.gs(R.string.careportal_profileswitch) + ": " + profileSwitch.profileName +
|
||||
"\n" + rh.gs(R.string.date) + ": " + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName,
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp))
|
||||
disposable += repository.runTransactionForResult(InvalidateProfileSwitchTransaction(profileSwitch.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.clone.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
val profileSwitch = (it.tag as ProfileSealed.PS).value
|
||||
val profileSealed = it.tag as ProfileSealed
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal_profileswitch), rh.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.getCustomizedName() + "\n" + dateUtil.dateAndTimeString(profileSwitch.timestamp), Runnable {
|
||||
uel.log(Action.PROFILE_SWITCH_CLONED, Sources.Treatments,
|
||||
OKDialog.showConfirmation(
|
||||
activity,
|
||||
rh.gs(R.string.careportal_profileswitch),
|
||||
rh.gs(R.string.copytolocalprofile) + "\n" + profileSwitch.getCustomizedName() + "\n" + dateUtil.dateAndTimeString(profileSwitch.timestamp),
|
||||
Runnable {
|
||||
uel.log(
|
||||
Action.PROFILE_SWITCH_CLONED, Sources.Treatments,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_"),
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp),
|
||||
ValueWithUnit.SimpleString(profileSwitch.profileName))
|
||||
ValueWithUnit.SimpleString(profileSwitch.profileName)
|
||||
)
|
||||
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
|
||||
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(nonCustomized, profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")))
|
||||
localProfilePlugin.addProfile(
|
||||
localProfilePlugin.copyFrom(
|
||||
nonCustomized,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_")
|
||||
)
|
||||
)
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.clone.paintFlags = binding.clone.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.name.setOnClickListener {
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
|
@ -266,4 +272,104 @@ class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_profile_switch, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_profile_switch, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
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())
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { _, profileSwitch ->
|
||||
uel.log(
|
||||
Action.PROFILE_SWITCH_REMOVED, Sources.Treatments, profileSwitch.profileName,
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateProfileSwitchTransaction(profileSwitch.id))
|
||||
.subscribe(
|
||||
{ result -> result.invalidated.forEach { aapsLogger.debug(LTag.DATABASE, "Invalidated ProfileSwitch $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating ProfileSwitch", it) }
|
||||
)
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
@ -30,6 +29,8 @@ import info.nightscout.androidaps.plugins.bus.RxBus
|
|||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment.RecyclerViewAdapter.TempTargetsViewHolder
|
||||
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
|
@ -40,6 +41,7 @@ import info.nightscout.androidaps.extensions.friendlyDescription
|
|||
import info.nightscout.androidaps.extensions.highValueToUnitsToString
|
||||
import info.nightscout.androidaps.extensions.lowValueToUnitsToString
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
|
@ -65,48 +67,55 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
|
||||
private var _binding: TreatmentsTemptargetFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// 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: SparseArray<TemporaryTarget> = SparseArray()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsTemptargetFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.refresheventsfromnightscout) + " ?", {
|
||||
uel.log(Action.TT_NS_REFRESH, Sources.Treatments)
|
||||
disposable += Completable.fromAction { repository.deleteAllTempTargetEntries() }
|
||||
}
|
||||
|
||||
private fun refreshFromNightscout() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.refresheventsfromnightscout) + "?") {
|
||||
uel.log(Action.TREATMENTS_NS_REFRESH, Sources.Treatments)
|
||||
disposable +=
|
||||
Completable.fromAction {
|
||||
repository.deleteAllEffectiveProfileSwitches()
|
||||
repository.deleteAllProfileSwitches()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTempTargetChange()) }
|
||||
onComplete = {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(0L))
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
|
||||
rxBus.send(EventNSClientRestart())
|
||||
})
|
||||
}
|
||||
}
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
if (nsUploadOnly) binding.refreshFromNightscout.visibility = View.INVISIBLE
|
||||
binding.showInvalidated.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable +=
|
||||
if (showInvalidated)
|
||||
repository
|
||||
.getTemporaryTargetDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
|
@ -145,6 +154,7 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -163,7 +173,18 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
val tempTarget = tempTargetList[position]
|
||||
holder.binding.ns.visibility = (tempTarget.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = tempTarget.isValid.not().toVisibility()
|
||||
holder.binding.remove.visibility = tempTarget.isValid.toVisibility()
|
||||
holder.binding.cbRemove.visibility = (tempTarget.isValid && removeActionMode != null).toVisibility()
|
||||
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())
|
||||
}
|
||||
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()
|
||||
holder.binding.date.text = dateUtil.dateString(tempTarget.timestamp)
|
||||
|
@ -177,43 +198,123 @@ class TreatmentsTempTargetFragment : DaggerFragment() {
|
|||
tempTarget.id == currentlyActiveTarget?.id -> rh.gc(R.color.colorActive)
|
||||
tempTarget.timestamp > dateUtil.now() -> rh.gc(R.color.colorScheduled)
|
||||
else -> holder.binding.reasonColon.currentTextColor
|
||||
})
|
||||
holder.binding.remove.tag = tempTarget
|
||||
}
|
||||
)
|
||||
val nextTimestamp = if (tempTargetList.size != position + 1) tempTargetList[position + 1].timestamp else 0L
|
||||
holder.binding.delimiter.visibility = dateUtil.isSameDay(tempTarget.timestamp, nextTimestamp).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = tempTargetList.size
|
||||
override fun getItemCount() = tempTargetList.size
|
||||
|
||||
inner class TempTargetsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = TreatmentsTemptargetItemBinding.bind(view)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val tempTarget = v.tag as TemporaryTarget
|
||||
context?.let { context ->
|
||||
OKDialog.showConfirmation(context, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${rh.gs(R.string.careportal_temporarytarget)}: ${tempTarget.friendlyDescription(profileFunction.getUnits(), rh)}
|
||||
${dateUtil.dateAndTimeString(tempTarget.timestamp)}
|
||||
""".trimIndent(),
|
||||
{ _: DialogInterface?, _: Int ->
|
||||
uel.log(Action.TT_REMOVED, Sources.Treatments,
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach { _, tempTarget ->
|
||||
uel.log(
|
||||
Action.TT_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempTarget.timestamp),
|
||||
ValueWithUnit.TherapyEventTTReason(tempTarget.reason),
|
||||
ValueWithUnit.Mgdl(tempTarget.lowTarget),
|
||||
ValueWithUnit.Mgdl(tempTarget.highTarget).takeIf { tempTarget.lowTarget != tempTarget.highTarget },
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tempTarget.duration).toInt()))
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(tempTarget.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryTargetTransaction(tempTarget.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temp target $tempTarget") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary target", it) })
|
||||
}, null)
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_temp_target, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
val nsUploadOnly = !sp.getBoolean(R.string.key_ns_receive_temp_target, false) || !buildHelper.isEngineeringMode()
|
||||
menu.findItem(R.id.nav_refresh_ns)?.isVisible = !nsUploadOnly
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_refresh_ns -> {
|
||||
refreshFromNightscout()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
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())
|
||||
}
|
||||
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Paint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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
|
||||
|
@ -36,6 +36,7 @@ import info.nightscout.shared.logging.LTag
|
|||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
|
@ -64,18 +65,22 @@ 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()
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
private var selectedItems: SparseArray<TemporaryBasal> = SparseArray()
|
||||
private var showInvalidated = false
|
||||
private var toolbar: Toolbar? = null
|
||||
private var removeActionMode: ActionMode? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsTempbasalsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
toolbar = activity?.findViewById(R.id.toolbar)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
@ -98,7 +103,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
val now = System.currentTimeMillis()
|
||||
disposable +=
|
||||
if (activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
tempBasalsWithInvalid(now)
|
||||
.zipWith(extendedBolusesWithInvalid(now)) { first, second -> first + second }
|
||||
.map { list -> list.filterNotNull() }
|
||||
|
@ -113,7 +118,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
} else {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
if (showInvalidated)
|
||||
tempBasalsWithInvalid(now)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
|
@ -150,6 +155,7 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
removeActionMode?.let { it.finish() }
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
@ -187,62 +193,147 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
|||
holder.binding.emulatedSuspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.EMULATED_PUMP_SUSPEND).toVisibility()
|
||||
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.remove.tag = tempBasal
|
||||
|
||||
holder.binding.cbRemove.visibility = (tempBasal.isValid && removeActionMode != null).toVisibility()
|
||||
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())
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = tempBasalList.size
|
||||
override fun getItemCount() = tempBasalList.size
|
||||
|
||||
inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsTempbasalsItemBinding.bind(itemView)
|
||||
|
||||
init {
|
||||
binding.remove.setOnClickListener { v: View ->
|
||||
val tempBasal = v.tag as TemporaryBasal
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_temp_basal, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_invalidated)?.isVisible = showInvalidated
|
||||
menu.findItem(R.id.nav_show_invalidated)?.isVisible = !showInvalidated
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_remove_items -> {
|
||||
removeActionMode = toolbar?.startActionMode(RemoveActionModeCallback())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_show_invalidated -> {
|
||||
showInvalidated = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_invalidated -> {
|
||||
showInvalidated = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
|
||||
inner class RemoveActionModeCallback : ActionMode.Callback {
|
||||
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu?): Boolean {
|
||||
mode.menuInflater.inflate(R.menu.menu_delete_selection, menu)
|
||||
selectedItems.clear()
|
||||
mode.title = rh.gs(R.string.count_selected, selectedItems.size())
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPrepareActionMode(mode: ActionMode?, menu: Menu?) = false
|
||||
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.remove_selected -> {
|
||||
removeSelected()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyActionMode(mode: ActionMode?) {
|
||||
removeActionMode = null
|
||||
binding.recyclerview.adapter?.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getConfirmationText(): String {
|
||||
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())
|
||||
}
|
||||
|
||||
private fun removeSelected() {
|
||||
if (selectedItems.size() > 0)
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.removerecord), getConfirmationText(), Runnable {
|
||||
selectedItems.forEach {_, tempBasal ->
|
||||
var extendedBolus: ExtendedBolus? = null
|
||||
val isFakeExtended = tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED
|
||||
if (isFakeExtended) {
|
||||
val eb = repository.getExtendedBolusActiveAt(tempBasal.timestamp).blockingGet()
|
||||
extendedBolus = if (eb is ValueWrapper.Existing) eb.value else null
|
||||
}
|
||||
val profile = profileFunction.getProfile(dateUtil.now())
|
||||
?: return@setOnClickListener
|
||||
context?.let {
|
||||
OKDialog.showConfirmation(it, rh.gs(R.string.removerecord),
|
||||
"""
|
||||
${if (isFakeExtended) rh.gs(R.string.extended_bolus) else rh.gs(R.string.tempbasal_label)}: ${tempBasal.toStringFull(profile, dateUtil)}
|
||||
${rh.gs(R.string.date)}: ${dateUtil.dateAndTimeString(tempBasal.timestamp)}
|
||||
""".trimIndent(),
|
||||
{ _: DialogInterface?, _: Int ->
|
||||
if (isFakeExtended && extendedBolus != null) {
|
||||
uel.log(Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
uel.log(
|
||||
Action.EXTENDED_BOLUS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt()))
|
||||
ValueWithUnit.Minute(TimeUnit.MILLISECONDS.toMinutes(extendedBolus.duration).toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateExtendedBolusTransaction(extendedBolus.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed extended bolus $extendedBolus") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating extended bolus", it) })
|
||||
} else if (!isFakeExtended) {
|
||||
uel.log(Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
||||
uel.log(
|
||||
Action.TEMP_BASAL_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(tempBasal.timestamp),
|
||||
if (tempBasal.isAbsolute) ValueWithUnit.UnitPerHour(tempBasal.rate) else ValueWithUnit.Percent(tempBasal.rate.toInt()),
|
||||
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt()))
|
||||
ValueWithUnit.Minute(T.msecs(tempBasal.duration).mins().toInt())
|
||||
)
|
||||
disposable += repository.runTransactionForResult(InvalidateTemporaryBasalTransaction(tempBasal.id))
|
||||
.subscribe(
|
||||
{ aapsLogger.debug(LTag.DATABASE, "Removed temporary basal $tempBasal") },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while invalidating temporary basal", it) })
|
||||
}
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
removeActionMode?.finish()
|
||||
})
|
||||
}
|
||||
else
|
||||
removeActionMode?.finish()
|
||||
}
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
|
@ -30,6 +28,7 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
|||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -51,11 +50,10 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
|
||||
private val millsToThePastFiltered = T.days(30).msecs()
|
||||
private val millsToThePastUnFiltered = T.days(3).msecs()
|
||||
|
||||
private var showLoop = false
|
||||
private var _binding: TreatmentsUserEntryFragmentBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
// This property is only valid between onCreateView and onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
|
@ -63,9 +61,12 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.ueExportToXml.setOnClickListener {
|
||||
}
|
||||
|
||||
fun exportUserEnteries() {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.ue_export_to_csv) + "?") {
|
||||
uel.log(Action.EXPORT_CSV, Sources.Treatments)
|
||||
|
@ -73,25 +74,20 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
}
|
||||
}
|
||||
}
|
||||
binding.showLoop.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showLoop.isChecked)
|
||||
disposable.add( repository
|
||||
disposable +=
|
||||
if (showLoop)
|
||||
repository
|
||||
.getUserEntryDataFromTime(now - millsToThePastUnFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
else
|
||||
disposable.add( repository
|
||||
repository
|
||||
.getUserEntryFilteredDataFromTime(now - millsToThePastFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -99,15 +95,15 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable.add(rxBus
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
disposable.add(rxBus
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
|
@ -152,7 +148,40 @@ class TreatmentsUserEntryFragment : DaggerFragment() {
|
|||
val binding = TreatmentsUserEntryItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = entries.size
|
||||
override fun getItemCount() = entries.size
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_treatments_user_entry, menu)
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
menu.findItem(R.id.nav_hide_loop)?.isVisible = showLoop
|
||||
menu.findItem(R.id.nav_show_loop)?.isVisible = !showLoop
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean =
|
||||
when (item.itemId) {
|
||||
R.id.nav_show_loop -> {
|
||||
showLoop = true
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_hide_loop -> {
|
||||
showLoop = false
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
true
|
||||
}
|
||||
|
||||
R.id.nav_export -> {
|
||||
exportUserEnteries()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
|
@ -1,54 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsBolusCarbsFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/nav_refreshtreatments" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/delete_future_treatments"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_remove"
|
||||
android:text="@string/deletefuturetreatments" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -161,14 +161,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/bolus_remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_bolus_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -257,13 +255,21 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/carbs_remove"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/cb_carbs_remove"
|
||||
android:visibility="gone"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -1,54 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/nav_refreshtreatments" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/remove_androidaps_started_events"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0px"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_remove"
|
||||
android:text="@string/careportal_removestartedevents" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -112,14 +112,12 @@
|
|||
android:text="Activity"
|
||||
tools:ignore="HardcodedText,RtlSymmetry" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,34 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsExtendedBolusesFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
app:srcCompat="@drawable/ic_visibility"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -153,14 +153,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.TreatmentsActivity">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:minHeight="?attr/actionBarSize"
|
||||
app:titleTextColor="@android:color/white" />
|
||||
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,44 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/refresheventsfromnightscout" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -124,15 +124,12 @@
|
|||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_blue_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="5dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,36 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTemporaryBasalsFragment">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -172,15 +172,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:visibility="gone"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -1,45 +1,10 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/refresh_from_nightscout"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_refresh"
|
||||
android:text="@string/refresheventsfromnightscout"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_invalidated"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_removed"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -147,14 +147,12 @@
|
|||
android:text="@string/invalid"
|
||||
android:textColor="@android:color/holo_red_light" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/remove"
|
||||
<CheckBox
|
||||
android:id="@+id/cb_remove"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/remove_button"
|
||||
android:textAlignment="viewEnd"
|
||||
android:textColor="@android:color/holo_orange_light" />
|
||||
android:contentDescription="@string/select_for_removal"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -6,40 +6,6 @@
|
|||
android:orientation="vertical"
|
||||
tools:context="info.nightscout.androidaps.activities.fragments.TreatmentsUserEntryFragment">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.SingleClickButton
|
||||
android:id="@+id/ue_export_to_xml"
|
||||
style="?android:attr/buttonStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_weight="1"
|
||||
android:drawableStart="@drawable/ic_header_export"
|
||||
android:text="@string/ue_export_to_csv" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/show_loop"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:checked="false"
|
||||
android:paddingEnd="5dp"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_calculation"
|
||||
app:srcCompat="@drawable/ic_loop_closed_white" />
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
|
|
11
app/src/main/res/menu/menu_delete_selection.xml
Normal file
11
app/src/main/res/menu/menu_delete_selection.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/remove_selected"
|
||||
android:icon="@drawable/ic_trash"
|
||||
android:iconTint="@color/white"
|
||||
android:title="@string/remove_selected_items"
|
||||
app:showAsAction="always" />
|
||||
|
||||
</menu>
|
25
app/src/main/res/menu/menu_treatments_carbs_bolus.xml
Normal file
25
app/src/main/res/menu/menu_treatments_carbs_bolus.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_delete_future"
|
||||
android:title="@string/delete_future_treatments"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
25
app/src/main/res/menu/menu_treatments_careportal.xml
Normal file
25
app/src/main/res/menu/menu_treatments_careportal.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_remove_started_events"
|
||||
android:title="@string/careportal_removestartedevents"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_extended_bolus.xml
Normal file
17
app/src/main/res/menu/menu_treatments_extended_bolus.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_profile_switch.xml
Normal file
17
app/src/main/res/menu/menu_treatments_profile_switch.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_temp_basal.xml
Normal file
17
app/src/main/res/menu/menu_treatments_temp_basal.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
21
app/src/main/res/menu/menu_treatments_temp_target.xml
Normal file
21
app/src/main/res/menu/menu_treatments_temp_target.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_remove_items"
|
||||
android:title="@string/remove_items"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_show_invalidated"
|
||||
android:title="@string/show_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_invalidated"
|
||||
android:title="@string/hide_invalidated"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_refresh_ns"
|
||||
android:title="@string/refresh_from_nightscout"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
17
app/src/main/res/menu/menu_treatments_user_entry.xml
Normal file
17
app/src/main/res/menu/menu_treatments_user_entry.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/nav_show_loop"
|
||||
android:title="@string/show_loop"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_hide_loop"
|
||||
android:title="@string/hide_loop"
|
||||
app:showAsAction="never" />
|
||||
<item
|
||||
android:id="@+id/nav_export"
|
||||
android:title="@string/ue_export_to_csv"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
|
@ -827,6 +827,9 @@
|
|||
<string name="sensitivity_raises_target_summary">When sensitivity is detected, raise the target glucose</string>
|
||||
<string name="key_keep_screen_on" translatable="false">keep_screen_on</string>
|
||||
<string name="careportal_removestartedevents">Clean AndroidAPS started</string>
|
||||
<string name="show_invalidated">Show invalidated</string>
|
||||
<string name="hide_invalidated">Hide invalidated</string>
|
||||
<string name="remove_items">Remove items</string>
|
||||
<string name="storedsettingsfound">Stored settings found</string>
|
||||
<string name="allow_hardware_pump_text">Attention: If you activate and connect to a hardware pump, AndroidAPS will copy the basal settings from the profile to the pump, overwriting the existing basal rate stored on the pump. Make sure you have the correct basal setting in AndroidAPS. If you are not sure or don\'t want to overwrite the basal settings on your pump, press cancel and repeat switching to the pump at a later time.</string>
|
||||
<string name="error_adding_treatment_title">Treatment data incomplete</string>
|
||||
|
@ -1208,4 +1211,14 @@
|
|||
<string name="wear_unknown_action_string">Unknown action command:</string>
|
||||
<string name="overview_editquickwizard_percentage">Percentage</string>
|
||||
<string name="app_default">Application default</string>
|
||||
<string name="refresh_from_nightscout">Refresh from Nightscout</string>
|
||||
<string name="remove_selected_items">Remove selected items</string>
|
||||
<string name="select_for_removal">Select for removal</string>
|
||||
<string name="profile_changes">Profile changes</string>
|
||||
<string name="tempt_targets">Temp Targets</string>
|
||||
<string name="carbs_and_bolus">Carbs and bolus</string>
|
||||
<string name="confirm_remove_multiple_items">Are you sure you want to remove %1$d items</string>
|
||||
<string name="hide_loop">Hide loop</string>
|
||||
<string name="show_loop">Show loop</string>
|
||||
<string name="count_selected">%1$d selected</string>
|
||||
</resources>
|
||||
|
|
10
core/src/main/res/drawable/ic_close.xml
Normal file
10
core/src/main/res/drawable/ic_close.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
|
||||
</vector>
|
|
@ -3,6 +3,8 @@
|
|||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionModeCloseDrawable">@drawable/ic_close</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
|
@ -469,6 +469,7 @@
|
|||
<string name="uel_stat_reset">STAT RESET</string>
|
||||
<string name="uel_delete_logs">DELETE LOGS</string>
|
||||
<string name="uel_delete_future_treatments">DELETE FUTURE TREATMENTS</string>
|
||||
<string name="delete_future_treatments">Delete future treatments</string>
|
||||
<string name="uel_export_settings">EXPORT SETTINGS</string>
|
||||
<string name="uel_import_settings">IMPORT SETTINGS</string>
|
||||
<string name="uel_reset_databases">RESET DATABASES</string>
|
||||
|
|
Loading…
Reference in a new issue