AutomationEvent new options, automation jetpack bindings

This commit is contained in:
Milos Kozak 2020-12-14 12:46:38 +01:00
parent 2c43bc75c0
commit 4d02587bb7
16 changed files with 198 additions and 123 deletions

View file

@ -135,6 +135,9 @@ android {
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = '1.8'
} }
buildFeatures {
viewBinding true
}
lintOptions { lintOptions {
checkReleaseBuilds false checkReleaseBuilds false
disable 'MissingTranslation' disable 'MissingTranslation'

View file

@ -15,12 +15,18 @@ import java.util.*
import javax.inject.Inject import javax.inject.Inject
class AutomationEvent(private val injector: HasAndroidInjector) { class AutomationEvent(private val injector: HasAndroidInjector) {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
var title: String? = null
var isEnabled = true
var systemAction: Boolean = false // true = generated by AAPS, false = entered by user
var readOnly: Boolean = false // removing, editing disabled
var autoRemove: Boolean = false // auto-remove once used
var trigger: Trigger = TriggerConnector(injector) var trigger: Trigger = TriggerConnector(injector)
val actions: MutableList<Action> = ArrayList() val actions: MutableList<Action> = ArrayList()
var title: String? = null
var isEnabled = true
var lastRun: Long = 0 var lastRun: Long = 0
init { init {
@ -43,6 +49,9 @@ class AutomationEvent(private val injector: HasAndroidInjector) {
return JSONObject() return JSONObject()
.put("title", title) .put("title", title)
.put("enabled", isEnabled) .put("enabled", isEnabled)
.put("systemAction", systemAction)
.put("readOnly", readOnly)
.put("autoRemove", autoRemove)
.put("trigger", trigger.toJSON()) .put("trigger", trigger.toJSON())
.put("actions", array) .put("actions", array)
.toString() .toString()
@ -52,6 +61,9 @@ class AutomationEvent(private val injector: HasAndroidInjector) {
val d = JSONObject(data) val d = JSONObject(data)
title = d.optString("title", "") title = d.optString("title", "")
isEnabled = d.optBoolean("enabled", true) isEnabled = d.optBoolean("enabled", true)
systemAction = d.optBoolean("systemAction", false)
readOnly = d.optBoolean("readOnly", false)
autoRemove = d.optBoolean("autoRemove", false)
trigger = TriggerDummy(injector).instantiate(JSONObject(d.getString("trigger"))) trigger = TriggerDummy(injector).instantiate(JSONObject(d.getString("trigger")))
?: TriggerConnector(injector) ?: TriggerConnector(injector)
val array = d.getJSONArray("actions") val array = d.getJSONArray("actions")

View file

@ -9,11 +9,8 @@ import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -21,6 +18,8 @@ import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.AutomationEventItemBinding
import info.nightscout.androidaps.databinding.AutomationFragmentBinding
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter
@ -34,14 +33,15 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation import info.nightscout.androidaps.utils.alertDialogs.OKDialog.showConfirmation
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_fragment.*
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
class AutomationFragment : DaggerFragment(), OnStartDragListener { class AutomationFragment : DaggerFragment(), OnStartDragListener {
@Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@ -53,20 +53,27 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
private var itemTouchHelper: ItemTouchHelper? = null private var itemTouchHelper: ItemTouchHelper? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { private var _binding: AutomationFragmentBinding? = null
return inflater.inflate(R.layout.automation_fragment, container, false)
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = AutomationFragmentBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
eventListAdapter = EventListAdapter() eventListAdapter = EventListAdapter()
automation_eventListView.layoutManager = LinearLayoutManager(context) binding.eventListView.layoutManager = LinearLayoutManager(context)
automation_eventListView.adapter = eventListAdapter binding.eventListView.adapter = eventListAdapter
automation_logView.movementMethod = ScrollingMovementMethod() binding.logView.movementMethod = ScrollingMovementMethod()
automation_fabAddEvent.setOnClickListener { binding.fabAddEvent.setOnClickListener {
val dialog = EditEventDialog() val dialog = EditEventDialog()
val args = Bundle() val args = Bundle()
args.putString("event", AutomationEvent(mainApp).toJSON()) args.putString("event", AutomationEvent(mainApp).toJSON())
@ -77,7 +84,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
val callback: ItemTouchHelper.Callback = SimpleItemTouchHelperCallback(eventListAdapter) val callback: ItemTouchHelper.Callback = SimpleItemTouchHelperCallback(eventListAdapter)
itemTouchHelper = ItemTouchHelper(callback) itemTouchHelper = ItemTouchHelper(callback)
itemTouchHelper?.attachToRecyclerView(automation_eventListView) itemTouchHelper?.attachToRecyclerView(binding.eventListView)
} }
@ -105,13 +112,18 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
disposable.clear() disposable.clear()
} }
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
@Synchronized @Synchronized
private fun updateGui() { private fun updateGui() {
eventListAdapter.notifyDataSetChanged() eventListAdapter.notifyDataSetChanged()
val sb = StringBuilder() val sb = StringBuilder()
for (l in automationPlugin.executionLog.reversed()) for (l in automationPlugin.executionLog.reversed())
sb.append(l).append("<br>") sb.append(l).append("<br>")
automation_logView?.text = HtmlHelper.fromHtml(sb.toString()) binding.logView.text = HtmlHelper.fromHtml(sb.toString())
} }
override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) { override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) {
@ -132,6 +144,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
} }
inner class EventListAdapter : RecyclerView.Adapter<EventListAdapter.ViewHolder>(), ItemTouchHelperAdapter { inner class EventListAdapter : RecyclerView.Adapter<EventListAdapter.ViewHolder>(), ItemTouchHelperAdapter {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_event_item, parent, false) val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_event_item, parent, false)
return ViewHolder(v, parent.context) return ViewHolder(v, parent.context)
@ -147,36 +160,38 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val event = automationPlugin.automationEvents[position] val event = automationPlugin.automationEvents[position]
holder.eventTitle.text = event.title holder.binding.eventTitle.text = event.title
holder.enabled.isChecked = event.isEnabled holder.binding.enabled.isChecked = event.isEnabled
holder.iconLayout.removeAllViews() holder.binding.enabled.isEnabled = !event.readOnly
holder.binding.iconLayout.removeAllViews()
// trigger icons // trigger icons
val triggerIcons = HashSet<Int>() val triggerIcons = HashSet<Int>()
fillIconSet(event.trigger as TriggerConnector, triggerIcons) fillIconSet(event.trigger as TriggerConnector, triggerIcons)
for (res in triggerIcons) { for (res in triggerIcons) {
addImage(res, holder.context, holder.iconLayout) addImage(res, holder.context, holder.binding.iconLayout)
} }
// arrow icon // arrow icon
val iv = ImageView(holder.context) val iv = ImageView(holder.context)
iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp) iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp)
iv.layoutParams = LinearLayout.LayoutParams(resourceHelper.dpToPx(24), resourceHelper.dpToPx(24)) iv.layoutParams = LinearLayout.LayoutParams(resourceHelper.dpToPx(24), resourceHelper.dpToPx(24))
iv.setPadding(resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4), 0) iv.setPadding(resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4), 0)
holder.iconLayout.addView(iv) holder.binding.iconLayout.addView(iv)
// action icons // action icons
val actionIcons = HashSet<Int>() val actionIcons = HashSet<Int>()
for (action in event.actions) { for (action in event.actions) {
actionIcons.add(action.icon()) actionIcons.add(action.icon())
} }
for (res in actionIcons) { for (res in actionIcons) {
addImage(res, holder.context, holder.iconLayout) addImage(res, holder.context, holder.binding.iconLayout)
} }
// enabled event // enabled event
holder.enabled.setOnClickListener { holder.binding.enabled.setOnClickListener {
event.isEnabled = holder.enabled.isChecked event.isEnabled = holder.binding.enabled.isChecked
rxBus.send(EventAutomationDataChanged()) rxBus.send(EventAutomationDataChanged())
} }
// edit event // edit event
holder.rootLayout.setOnClickListener { if (!event.readOnly)
holder.binding.rootLayout.setOnClickListener {
val dialog = EditEventDialog() val dialog = EditEventDialog()
val args = Bundle() val args = Bundle()
args.putString("event", event.toJSON()) args.putString("event", event.toJSON())
@ -185,7 +200,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
dialog.show(childFragmentManager, "EditEventDialog") dialog.show(childFragmentManager, "EditEventDialog")
} }
// Start a drag whenever the handle view it touched // Start a drag whenever the handle view it touched
holder.iconSort.setOnTouchListener { v: View, motionEvent: MotionEvent -> holder.binding.iconSort.setOnTouchListener { v: View, motionEvent: MotionEvent ->
if (motionEvent.action == MotionEvent.ACTION_DOWN) { if (motionEvent.action == MotionEvent.ACTION_DOWN) {
this@AutomationFragment.onStartDrag(holder) this@AutomationFragment.onStartDrag(holder)
return@setOnTouchListener true return@setOnTouchListener true
@ -193,16 +208,18 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
v.onTouchEvent(motionEvent) v.onTouchEvent(motionEvent)
} }
// remove event // remove event
holder.iconTrash.setOnClickListener { holder.binding.iconTrash.setOnClickListener {
showConfirmation(requireContext(), resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.automationEvents[position].title, showConfirmation(requireContext(), resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.automationEvents[position].title,
Runnable { Runnable {
automationPlugin.automationEvents.removeAt(position) automationPlugin.automationEvents.removeAt(position)
notifyItemRemoved(position) notifyItemRemoved(position)
rxBus.send(EventAutomationDataChanged()) rxBus.send(EventAutomationDataChanged())
rxBus.send(EventAutomationUpdateGui()) rxBus.send(EventAutomationUpdateGui())
}, Runnable { rxBus.send(EventAutomationUpdateGui()) }, Runnable {
rxBus.send(EventAutomationUpdateGui())
}) })
} }
holder.binding.iconTrash.visibility = (!event.readOnly).toVisibility()
} }
override fun getItemCount(): Int = automationPlugin.automationEvents.size override fun getItemCount(): Int = automationPlugin.automationEvents.size
@ -227,12 +244,8 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
} }
inner class ViewHolder(view: View, val context: Context) : RecyclerView.ViewHolder(view), ItemTouchHelperViewHolder { inner class ViewHolder(view: View, val context: Context) : RecyclerView.ViewHolder(view), ItemTouchHelperViewHolder {
val rootLayout: RelativeLayout = view.findViewById(R.id.rootLayout)
val iconLayout: LinearLayout = view.findViewById(R.id.iconLayout) val binding = AutomationEventItemBinding.bind(view)
val eventTitle: TextView = view.findViewById(R.id.viewEventTitle)
val iconTrash: ImageView = view.findViewById(R.id.iconTrash)
val iconSort: ImageView = view.findViewById(R.id.iconSort)
val enabled: CheckBox = view.findViewById(R.id.automation_enabled)
override fun onItemSelected() = itemView.setBackgroundColor(Color.LTGRAY) override fun onItemSelected() = itemView.setBackgroundColor(Color.LTGRAY)

View file

@ -6,24 +6,30 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.RadioButton import android.widget.RadioButton
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.AutomationDialogChooseActionBinding
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.actions.Action import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import kotlinx.android.synthetic.main.automation_dialog_choose_action.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor import kotlin.reflect.full.primaryConstructor
class ChooseActionDialog : DialogFragmentWithDate() { class ChooseActionDialog : DialogFragmentWithDate() {
@Inject lateinit var automationPlugin: AutomationPlugin @Inject lateinit var automationPlugin: AutomationPlugin
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
private var checkedIndex = -1 private var checkedIndex = -1
private var _binding: AutomationDialogChooseActionBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
// restore checked radio button // restore checked radio button
@ -32,7 +38,8 @@ class ChooseActionDialog : DialogFragmentWithDate() {
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_choose_action, container, false) _binding = AutomationDialogChooseActionBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -42,11 +49,16 @@ class ChooseActionDialog : DialogFragmentWithDate() {
val radioButton = RadioButton(context) val radioButton = RadioButton(context)
radioButton.setText(a.friendlyName()) radioButton.setText(a.friendlyName())
radioButton.tag = a.javaClass.name radioButton.tag = a.javaClass.name
automation_radioGroup.addView(radioButton) binding.radioGroup.addView(radioButton)
} }
if (checkedIndex != -1) if (checkedIndex != -1)
(automation_radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true (binding.radioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
} }
override fun submit(): Boolean { override fun submit(): Boolean {
@ -70,16 +82,16 @@ class ChooseActionDialog : DialogFragmentWithDate() {
} }
private fun getActionClass(): String? { private fun getActionClass(): String? {
val radioButtonID = automation_radioGroup.checkedRadioButtonId val radioButtonID = binding.radioGroup.checkedRadioButtonId
val radioButton = automation_radioGroup.findViewById<RadioButton>(radioButtonID) val radioButton = binding.radioGroup.findViewById<RadioButton>(radioButtonID)
return radioButton?.let { return radioButton?.let {
it.tag as String it.tag as String
} }
} }
private fun determineCheckedIndex(): Int { private fun determineCheckedIndex(): Int {
for (i in 0 until automation_radioGroup.childCount) { for (i in 0 until binding.radioGroup.childCount) {
if ((automation_radioGroup.getChildAt(i) as RadioButton).isChecked) if ((binding.radioGroup.getChildAt(i) as RadioButton).isChecked)
return i return i
} }
return -1 return -1

View file

@ -6,34 +6,42 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.RadioButton import android.widget.RadioButton
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.AutomationDialogChooseTriggerBinding
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.*
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor import kotlin.reflect.full.primaryConstructor
class ChooseTriggerDialog : DialogFragmentWithDate() { class ChooseTriggerDialog : DialogFragmentWithDate() {
@Inject lateinit var automationPlugin: AutomationPlugin @Inject lateinit var automationPlugin: AutomationPlugin
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
private var checkedIndex = -1 private var checkedIndex = -1
private var clickListener: OnClickListener? = null private var clickListener: OnClickListener? = null
private var _binding: AutomationDialogChooseTriggerBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
interface OnClickListener { interface OnClickListener {
fun onClick(newTriggerObject: Trigger) fun onClick(newTriggerObject: Trigger)
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View {
// restore checked radio button // restore checked radio button
savedInstanceState?.let { bundle -> savedInstanceState?.let { bundle ->
checkedIndex = bundle.getInt("checkedIndex") checkedIndex = bundle.getInt("checkedIndex")
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false) _binding = AutomationDialogChooseTriggerBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -43,11 +51,16 @@ class ChooseTriggerDialog : DialogFragmentWithDate() {
val radioButton = RadioButton(context) val radioButton = RadioButton(context)
radioButton.setText(t.friendlyName()) radioButton.setText(t.friendlyName())
radioButton.tag = t.javaClass.name radioButton.tag = t.javaClass.name
automation_chooseTriggerRadioGroup.addView(radioButton) binding.chooseTriggerRadioGroup.addView(radioButton)
} }
if (checkedIndex != -1) if (checkedIndex != -1)
(automation_chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true (binding.chooseTriggerRadioGroup.getChildAt(checkedIndex) as RadioButton).isChecked = true
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
} }
override fun submit(): Boolean { override fun submit(): Boolean {
@ -74,16 +87,16 @@ class ChooseTriggerDialog : DialogFragmentWithDate() {
} }
private fun getTriggerClass(): String? { private fun getTriggerClass(): String? {
val radioButtonID = automation_chooseTriggerRadioGroup.checkedRadioButtonId val radioButtonID = binding.chooseTriggerRadioGroup.checkedRadioButtonId
val radioButton = automation_chooseTriggerRadioGroup.findViewById<RadioButton>(radioButtonID) val radioButton = binding.chooseTriggerRadioGroup.findViewById<RadioButton>(radioButtonID)
return radioButton?.let { return radioButton?.let {
it.tag as String it.tag as String
} }
} }
private fun determineCheckedIndex(): Int { private fun determineCheckedIndex(): Int {
for (i in 0 until automation_chooseTriggerRadioGroup.childCount) { for (i in 0 until binding.chooseTriggerRadioGroup.childCount) {
if ((automation_chooseTriggerRadioGroup.getChildAt(i) as RadioButton).isChecked) if ((binding.chooseTriggerRadioGroup.getChildAt(i) as RadioButton).isChecked)
return i return i
} }
return -1 return -1

View file

@ -5,41 +5,48 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.AutomationDialogActionBinding
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.actions.Action import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.actions.ActionDummy import info.nightscout.androidaps.plugins.general.automation.actions.ActionDummy
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
import kotlinx.android.synthetic.main.automation_dialog_action.*
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
class EditActionDialog : DialogFragmentWithDate() { class EditActionDialog : DialogFragmentWithDate() {
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
private var action: Action? = null private var action: Action? = null
private var actionPosition: Int = -1 private var actionPosition: Int = -1
private var _binding: AutomationDialogActionBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View {
// load data from bundle // load data from bundle
(savedInstanceState ?: arguments)?.let { bundle -> (savedInstanceState ?: arguments)?.let { bundle ->
actionPosition = bundle.getInt("actionPosition", -1) actionPosition = bundle.getInt("actionPosition", -1)
bundle.getString("action")?.let { action = ActionDummy(mainApp).instantiate(JSONObject(it)) } bundle.getString("action")?.let { action = ActionDummy(mainApp).instantiate(JSONObject(it)) }
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_action, container, false) _binding = AutomationDialogActionBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
action?.let { action?.let {
automation_actionTitle.setText(it.friendlyName()) binding.actionTitle.setText(it.friendlyName())
automation_editActionLayout.removeAllViews() binding.editActionLayout.removeAllViews()
it.generateDialog(automation_editActionLayout) it.generateDialog(binding.editActionLayout)
} }
} }

View file

@ -11,6 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.databinding.AutomationDialogEventBinding
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
@ -27,10 +28,10 @@ import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_dialog_event.*
import javax.inject.Inject import javax.inject.Inject
class EditEventDialog : DialogFragmentWithDate() { class EditEventDialog : DialogFragmentWithDate() {
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@ -42,8 +43,14 @@ class EditEventDialog : DialogFragmentWithDate() {
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
private var _binding: AutomationDialogEventBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View {
event = AutomationEvent(mainApp) event = AutomationEvent(mainApp)
// load data from bundle // load data from bundle
(savedInstanceState ?: arguments)?.let { bundle -> (savedInstanceState ?: arguments)?.let { bundle ->
@ -52,16 +59,17 @@ class EditEventDialog : DialogFragmentWithDate() {
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_event, container, false) _binding = AutomationDialogEventBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
automation_inputEventTitle.setText(event.title) binding.inputEventTitle.setText(event.title)
automation_triggerDescription.text = event.trigger.friendlyDescription() binding.triggerDescription.text = event.trigger.friendlyDescription()
automation_editTrigger.setOnClickListener { binding.editTrigger.setOnClickListener {
val args = Bundle() val args = Bundle()
args.putString("trigger", event.trigger.toJSON()) args.putString("trigger", event.trigger.toJSON())
val dialog = EditTriggerDialog() val dialog = EditTriggerDialog()
@ -71,10 +79,10 @@ class EditEventDialog : DialogFragmentWithDate() {
// setup action list view // setup action list view
actionListAdapter = ActionListAdapter() actionListAdapter = ActionListAdapter()
automation_actionListView.layoutManager = LinearLayoutManager(context) binding.actionListView.layoutManager = LinearLayoutManager(context)
automation_actionListView.adapter = actionListAdapter binding.actionListView.adapter = actionListAdapter
automation_addAction.setOnClickListener { ChooseActionDialog().show(childFragmentManager, "ChooseActionDialog") } binding.addAction.setOnClickListener { ChooseActionDialog().show(childFragmentManager, "ChooseActionDialog") }
showPreconditions() showPreconditions()
@ -99,7 +107,7 @@ class EditEventDialog : DialogFragmentWithDate() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
event.trigger = it.trigger event.trigger = it.trigger
automation_triggerDescription.text = event.trigger.friendlyDescription() binding.triggerDescription.text = event.trigger.friendlyDescription()
}, { fabricPrivacy.logException(it) } }, { fabricPrivacy.logException(it) }
) )
disposable += rxBus disposable += rxBus
@ -113,7 +121,7 @@ class EditEventDialog : DialogFragmentWithDate() {
override fun submit(): Boolean { override fun submit(): Boolean {
// check for title // check for title
val title = automation_inputEventTitle?.text?.toString() ?: return false val title = binding.inputEventTitle.text?.toString() ?: return false
if (title.isEmpty()) { if (title.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name) ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
return false return false
@ -143,6 +151,7 @@ class EditEventDialog : DialogFragmentWithDate() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
disposable.clear() disposable.clear()
_binding = null
} }
override fun onSaveInstanceState(savedInstanceState: Bundle) { override fun onSaveInstanceState(savedInstanceState: Bundle) {
@ -154,12 +163,12 @@ class EditEventDialog : DialogFragmentWithDate() {
private fun showPreconditions() { private fun showPreconditions() {
val forcedTriggers = event.getPreconditions() val forcedTriggers = event.getPreconditions()
if (forcedTriggers.size() > 0) { if (forcedTriggers.size() > 0) {
automation_forcedTriggerDescription.visibility = View.VISIBLE binding.forcedTriggerDescription.visibility = View.VISIBLE
automation_forcedTriggerDescriptionLabel.visibility = View.VISIBLE binding.forcedTriggerDescriptionLabel.visibility = View.VISIBLE
automation_forcedTriggerDescription.text = forcedTriggers.friendlyDescription() binding.forcedTriggerDescription.text = forcedTriggers.friendlyDescription()
} else { } else {
automation_forcedTriggerDescription.visibility = View.GONE binding.forcedTriggerDescription.visibility = View.GONE
automation_forcedTriggerDescriptionLabel.visibility = View.GONE binding.forcedTriggerDescriptionLabel.visibility = View.GONE
} }
} }

View file

@ -5,7 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.AutomationDialogEditTriggerBinding
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
@ -19,11 +19,11 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
class EditTriggerDialog : DialogFragmentWithDate() { class EditTriggerDialog : DialogFragmentWithDate() {
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var mainApp: MainApp @Inject lateinit var mainApp: MainApp
@Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var fabricPrivacy: FabricPrivacy
@ -32,15 +32,22 @@ class EditTriggerDialog : DialogFragmentWithDate() {
private var triggers: Trigger? = null private var triggers: Trigger? = null
private var _binding: AutomationDialogEditTriggerBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View {
// load data from bundle // load data from bundle
(savedInstanceState ?: arguments)?.let { bundle -> (savedInstanceState ?: arguments)?.let { bundle ->
bundle.getString("trigger")?.let { triggers = TriggerDummy(mainApp).instantiate(JSONObject(it)) } bundle.getString("trigger")?.let { triggers = TriggerDummy(mainApp).instantiate(JSONObject(it)) }
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false) _binding = AutomationDialogEditTriggerBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -50,16 +57,16 @@ class EditTriggerDialog : DialogFragmentWithDate() {
.toObservable(EventTriggerChanged::class.java) .toObservable(EventTriggerChanged::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
automation_layoutTrigger.removeAllViews() binding.layoutTrigger.removeAllViews()
triggers?.generateDialog(automation_layoutTrigger) triggers?.generateDialog(binding.layoutTrigger)
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
disposable += rxBus disposable += rxBus
.toObservable(EventTriggerRemove::class.java) .toObservable(EventTriggerRemove::class.java)
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
findParent(triggers, it.trigger)?.list?.remove(it.trigger) findParent(triggers, it.trigger)?.list?.remove(it.trigger)
automation_layoutTrigger.removeAllViews() binding.layoutTrigger.removeAllViews()
triggers?.generateDialog(automation_layoutTrigger) triggers?.generateDialog(binding.layoutTrigger)
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
disposable += rxBus disposable += rxBus
@ -67,17 +74,18 @@ class EditTriggerDialog : DialogFragmentWithDate() {
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
findParent(triggers, it.trigger)?.list?.add(it.trigger.duplicate()) findParent(triggers, it.trigger)?.list?.add(it.trigger.duplicate())
automation_layoutTrigger.removeAllViews() binding.layoutTrigger.removeAllViews()
triggers?.generateDialog(automation_layoutTrigger) triggers?.generateDialog(binding.layoutTrigger)
}, { fabricPrivacy.logException(it) }) }, { fabricPrivacy.logException(it) })
// display root trigger // display root trigger
triggers?.generateDialog(automation_layoutTrigger) triggers?.generateDialog(binding.layoutTrigger)
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
disposable.clear() disposable.clear()
_binding = null
} }
override fun submit(): Boolean { override fun submit(): Boolean {

View file

@ -29,7 +29,7 @@
app:srcCompat="@drawable/ic_action_orange_48dp" /> app:srcCompat="@drawable/ic_action_orange_48dp" />
<TextView <TextView
android:id="@+id/automation_actionTitle" android:id="@+id/actionTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
@ -49,7 +49,7 @@
android:padding="5dp" /> android:padding="5dp" />
<LinearLayout <LinearLayout
android:id="@+id/automation_editActionLayout" android:id="@+id/editActionLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"

View file

@ -29,7 +29,6 @@
app:srcCompat="@drawable/ic_action_orange_48dp" /> app:srcCompat="@drawable/ic_action_orange_48dp" />
<TextView <TextView
android:id="@+id/actions_care_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
@ -50,7 +49,7 @@
android:padding="5dp" /> android:padding="5dp" />
<RadioGroup <RadioGroup
android:id="@+id/automation_radioGroup" android:id="@+id/radioGroup"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="10dp" /> android:padding="10dp" />

View file

@ -29,7 +29,6 @@
app:srcCompat="@drawable/ic_trigger_green_48dp" /> app:srcCompat="@drawable/ic_trigger_green_48dp" />
<TextView <TextView
android:id="@+id/actions_care_title"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
@ -43,7 +42,7 @@
</RelativeLayout> </RelativeLayout>
<RadioGroup <RadioGroup
android:id="@+id/automation_chooseTriggerRadioGroup" android:id="@+id/chooseTriggerRadioGroup"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:padding="10dp"/> android:padding="10dp"/>

View file

@ -29,7 +29,6 @@
app:srcCompat="@drawable/ic_trigger_green_48dp" /> app:srcCompat="@drawable/ic_trigger_green_48dp" />
<TextView <TextView
android:id="@+id/automation_actionTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerInParent="true" android:layout_centerInParent="true"
@ -43,7 +42,7 @@
</RelativeLayout> </RelativeLayout>
<LinearLayout <LinearLayout
android:id="@+id/automation_layoutTrigger" android:id="@+id/layoutTrigger"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="10dp" android:padding="10dp"

View file

@ -55,7 +55,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/automation_inputEventTitle" android:id="@+id/inputEventTitle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/taskname" /> android:hint="@string/taskname" />
@ -81,7 +81,7 @@
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/automation_editTrigger" android:id="@+id/editTrigger"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
@ -94,7 +94,7 @@
</RelativeLayout> </RelativeLayout>
<TextView <TextView
android:id="@+id/automation_triggerDescription" android:id="@+id/triggerDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
@ -102,14 +102,14 @@
android:orientation="vertical" /> android:orientation="vertical" />
<TextView <TextView
android:id="@+id/automation_forcedTriggerDescriptionLabel" android:id="@+id/forcedTriggerDescriptionLabel"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/preconditions" android:text="@string/preconditions"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/automation_forcedTriggerDescription" android:id="@+id/forcedTriggerDescription"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
@ -144,7 +144,7 @@
android:textStyle="bold" /> android:textStyle="bold" />
<TextView <TextView
android:id="@+id/automation_addAction" android:id="@+id/addAction"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
@ -157,7 +157,7 @@
</RelativeLayout> </RelativeLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/automation_actionListView" android:id="@+id/actionListView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"

View file

@ -14,22 +14,22 @@
android:padding="8dp"> android:padding="8dp">
<CheckBox <CheckBox
android:id="@+id/automation_enabled" android:id="@+id/enabled"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="true" /> android:layout_alignParentTop="true" />
<TextView <TextView
android:id="@+id/viewEventTitle" android:id="@+id/eventTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignTop="@+id/automation_enabled" android:layout_alignTop="@+id/enabled"
android:layout_alignBottom="@+id/automation_enabled" android:layout_alignBottom="@+id/enabled"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:layout_toStartOf="@+id/iconTrash" android:layout_toStartOf="@+id/iconTrash"
android:layout_toEndOf="@id/automation_enabled" android:layout_toEndOf="@id/enabled"
android:text="Title" android:text="Title"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textStyle="bold" /> android:textStyle="bold" />
@ -59,7 +59,7 @@
android:id="@+id/iconLayout" android:id="@+id/iconLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/automation_enabled" android:layout_below="@id/enabled"
android:orientation="horizontal" /> android:orientation="horizontal" />

View file

@ -6,23 +6,23 @@
tools:context="info.nightscout.androidaps.plugins.general.automation.AutomationFragment"> tools:context="info.nightscout.androidaps.plugins.general.automation.AutomationFragment">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/automation_eventListView" android:id="@+id/eventListView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_above="@+id/automation_logView" android:layout_above="@+id/logView"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:layout_marginBottom="15dp" /> android:layout_marginBottom="15dp" />
<TextView <TextView
android:id="@+id/automation_logView" android:id="@+id/logView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="100dp" android:layout_height="100dp"
android:scrollbars = "vertical" android:scrollbars = "vertical"
android:layout_alignParentBottom="true" /> android:layout_alignParentBottom="true" />
<com.google.android.material.floatingactionbutton.FloatingActionButton <com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/automation_fabAddEvent" android:id="@+id/fabAddEvent"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
@ -32,6 +32,7 @@
android:clickable="true" android:clickable="true"
android:focusable="true" android:focusable="true"
android:src="@drawable/ic_add_black_24dp" android:src="@drawable/ic_add_black_24dp"
tools:ignore="RelativeOverlap" /> tools:ignore="RelativeOverlap"
android:contentDescription="@string/addnew" />
</RelativeLayout> </RelativeLayout>

View file

@ -51,7 +51,7 @@ class AutomationEventTest : TestBase() {
event.addAction(ActionLoopEnable(injector)) event.addAction(ActionLoopEnable(injector))
// export to json // export to json
val eventJsonExpected = "{\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}" val eventJsonExpected = "{\"autoRemove\":false,\"readOnly\":false,\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"systemAction\":false,\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}"
Assert.assertEquals(eventJsonExpected, event.toJSON()) Assert.assertEquals(eventJsonExpected, event.toJSON())
// clone // clone