Merge pull request #1200 from Andries-Smit/a11y/overview

a11y overview screen reader accessibility
This commit is contained in:
Milos Kozak 2022-02-11 12:14:00 +01:00 committed by GitHub
commit 22670943be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 258 additions and 138 deletions

View file

@ -274,17 +274,25 @@ class WizardDialog : DaggerDialogFragment() {
private fun processCobCheckBox() {
if (binding.cobCheckbox.isChecked) {
binding.iobCheckbox.isEnabled = false
binding.iobCheckboxIcon.isEnabled = false
binding.iobCheckbox.isChecked = true
} else {
binding.iobCheckbox.isEnabled = true
binding.iobCheckboxIcon.isEnabled = true
}
}
private fun processEnabledIcons() {
binding.bgCheckboxIcon.isChecked = binding.bgCheckbox.isChecked
binding.trendCheckboxIcon.isChecked = binding.bgTrendCheckbox.isChecked
binding.iobCheckboxIcon.isChecked = binding.iobCheckbox.isChecked
binding.cobCheckboxIcon.isChecked = binding.cobCheckbox.isChecked
binding.bgCheckboxIcon.alpha = if (binding.bgCheckbox.isChecked) 1.0f else 0.2f
binding.trendCheckboxIcon.alpha = if (binding.bgTrendCheckbox.isChecked) 1.0f else 0.2f
binding.iobCheckboxIcon.alpha = if (binding.iobCheckbox.isChecked) 1.0f else 0.2f
binding.cobCheckboxIcon.alpha = if (binding.cobCheckbox.isChecked) 1.0f else 0.2f
binding.bgCheckboxIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
binding.trendCheckboxIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
binding.iobCheckboxIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()

View file

@ -102,4 +102,11 @@ class BgQualityCheckPlugin @Inject constructor(
State.RECALCULATED -> R.drawable.ic_baseline_warning_24_yellow
State.DOUBLED -> R.drawable.ic_baseline_warning_24_red
}
fun stateDescription(): String =
when (state) {
State.RECALCULATED -> rh.gs(R.string.a11y_bg_quality_recalculated)
State.DOUBLED -> rh.gs(R.string.a11y_bg_quality_doubles)
else -> ""
}
}

View file

@ -128,14 +128,29 @@ class OverviewData @Inject constructor(
var lastBg: GlucoseValue? = null
val lastBgColor: Int
val isLow: Boolean
get() = lastBg?.let { lastBg ->
when {
lastBg.valueToUnits(profileFunction.getUnits()) < defaultValueHelper.determineLowLine() -> rh.gc(R.color.low)
lastBg.valueToUnits(profileFunction.getUnits()) > defaultValueHelper.determineHighLine() -> rh.gc(R.color.high)
lastBg.valueToUnits(profileFunction.getUnits()) < defaultValueHelper.determineLowLine()
} ?: false
val isHigh: Boolean
get() = lastBg?.let { lastBg ->
lastBg.valueToUnits(profileFunction.getUnits()) > defaultValueHelper.determineHighLine()
} ?: false
val lastBgColor: Int
get() = when {
isLow -> rh.gc(R.color.low)
isHigh -> rh.gc(R.color.high)
else -> rh.gc(R.color.inrange)
}
} ?: rh.gc(R.color.inrange)
val lastBgDescription: String
get() = when {
isLow -> rh.gs(R.string.a11y_low)
isHigh -> rh.gs(R.string.a11y_high)
else -> rh.gs(R.string.a11y_inrange)
}
val isActualBg: Boolean
get() =

View file

@ -8,6 +8,7 @@ import android.content.Intent
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.AnimationDrawable
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
@ -597,24 +598,36 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
// aps mode
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
fun apsModeSetA11yLabel(stringRes: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
binding.infoLayout.apsMode.stateDescription = rh.gs(stringRes)
} else {
binding.infoLayout.apsMode.contentDescription = rh.gs(R.string.apsmode_title) + " " + rh.gs(stringRes)
}
}
if (config.APS && pump.pumpDescription.isTempBasalCapable) {
binding.infoLayout.apsMode.visibility = View.VISIBLE
binding.infoLayout.timeLayout.visibility = View.GONE
when {
(loop as PluginBase).isEnabled() && loop.isSuperBolus -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_superbolus)
apsModeSetA11yLabel(R.string.superbolus)
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE
}
loop.isDisconnected -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disconnected)
apsModeSetA11yLabel(R.string.disconnected)
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE
}
(loop as PluginBase).isEnabled() && loop.isSuspended -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_paused)
apsModeSetA11yLabel(R.string.suspendloop_label)
binding.infoLayout.apsModeText.text = dateUtil.age(loop.minutesToEndOfSuspend() * 60000L, true, rh)
binding.infoLayout.apsModeText.visibility = View.VISIBLE
}
@ -624,8 +637,10 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
if (pump.model() == PumpType.OMNIPOD_EROS || pump.model() == PumpType.OMNIPOD_DASH) {
// For Omnipod, indicate the pump as disconnected when it's suspended.
// The only way to 'reconnect' it, is through the Omnipod tab
apsModeSetA11yLabel(R.string.disconnected)
R.drawable.ic_loop_disconnected
} else {
apsModeSetA11yLabel(R.string.pump_paused)
R.drawable.ic_loop_paused
}
)
@ -634,21 +649,25 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() && loop.isLGS -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_lgs)
apsModeSetA11yLabel(R.string.uel_lgs_loop_mode)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_closed)
apsModeSetA11yLabel(R.string.closedloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
(loop as PluginBase).isEnabled() && !closedLoopEnabled.value() -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_open)
apsModeSetA11yLabel(R.string.openloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
else -> {
binding.infoLayout.apsMode.setImageResource(R.drawable.ic_loop_disabled)
apsModeSetA11yLabel(R.string.disabledloop)
binding.infoLayout.apsModeText.visibility = View.GONE
}
}
@ -732,6 +751,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.bg.setTextColor(overviewData.lastBgColor)
binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(overviewData.lastBg).directionToIcon())
binding.infoLayout.arrow.setColorFilter(overviewData.lastBgColor)
binding.infoLayout.arrow.contentDescription = overviewData.lastBgDescription + " " + rh.gs(R.string.and) + " " + trendCalculator.getTrendDescription(overviewData.lastBg)
val glucoseStatus = glucoseStatusProvider.glucoseStatusData
if (glucoseStatus != null) {
@ -751,13 +771,20 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
binding.infoLayout.bg.paintFlags =
if (!overviewData.isActualBg) binding.infoLayout.bg.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
else binding.infoLayout.bg.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
val outDate = (if (!overviewData.isActualBg) rh.gs(R.string.a11y_bg_outdated) else "")
binding.infoLayout.bg.contentDescription =
rh.gs(R.string.a11y_blood_glucose) + " " + binding.infoLayout.bg.text.toString() + " " + overviewData.lastBgDescription + " " + outDate
binding.infoLayout.timeAgo.text = dateUtil.minAgo(rh, overviewData.lastBg?.timestamp)
binding.infoLayout.timeAgo.contentDescription = dateUtil.minAgoLong(rh, overviewData.lastBg?.timestamp)
binding.infoLayout.timeAgoShort.text = "(" + dateUtil.minAgoShort(overviewData.lastBg?.timestamp) + ")"
val qualityIcon = bgQualityCheckPlugin.icon()
if (qualityIcon != 0) {
binding.infoLayout.bgQuality.visibility = View.VISIBLE
binding.infoLayout.bgQuality.setImageResource(qualityIcon)
binding.infoLayout.bgQuality.contentDescription = rh.gs(R.string.a11y_bg_quality) + " " + bgQualityCheckPlugin.stateDescription()
binding.infoLayout.bgQuality.setOnClickListener {
context?.let { context -> OKDialog.show(context, rh.gs(R.string.data_status), bgQualityCheckPlugin.message) }
}

View file

@ -1,29 +1,46 @@
package info.nightscout.androidaps.utils
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.GlucoseValue.TrendArrow.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TrendCalculator @Inject constructor(
private val repository: AppRepository
private val repository: AppRepository,
private val rh: ResourceHelper
) {
fun getTrendArrow(glucoseValue: GlucoseValue?): GlucoseValue.TrendArrow =
when {
glucoseValue?.trendArrow == null -> GlucoseValue.TrendArrow.NONE
glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE -> glucoseValue.trendArrow
glucoseValue?.trendArrow == null -> NONE
glucoseValue.trendArrow != NONE -> glucoseValue.trendArrow
else -> calculateDirection(glucoseValue)
}
fun getTrendDescription(glucoseValue: GlucoseValue?): String =
when (getTrendArrow(glucoseValue)) {
DOUBLE_DOWN -> rh.gs(R.string.a11y_arrow_double_down)
SINGLE_DOWN -> rh.gs(R.string.a11y_arrow_single_down)
FORTY_FIVE_DOWN -> rh.gs(R.string.a11y_arrow_forty_five_down)
FLAT -> rh.gs(R.string.a11y_arrow_flat)
FORTY_FIVE_UP -> rh.gs(R.string.a11y_arrow_forty_five_up)
SINGLE_UP -> rh.gs(R.string.a11y_arrow_single_up)
DOUBLE_UP -> rh.gs(R.string.a11y_arrow_double_up)
NONE -> rh.gs(R.string.a11y_arrow_none)
else -> rh.gs(R.string.a11y_arrow_unknown)
}
private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow {
val toTime = glucoseValue.timestamp
val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet()
if (readings.size < 2)
return GlucoseValue.TrendArrow.NONE
return NONE
val current = readings[0]
val previous = readings[1]
@ -35,14 +52,14 @@ class TrendCalculator @Inject constructor(
val slopeByMinute = slope * 60000
return when {
slopeByMinute <= -3.5 -> GlucoseValue.TrendArrow.DOUBLE_DOWN
slopeByMinute <= -2 -> GlucoseValue.TrendArrow.SINGLE_DOWN
slopeByMinute <= -1 -> GlucoseValue.TrendArrow.FORTY_FIVE_DOWN
slopeByMinute <= 1 -> GlucoseValue.TrendArrow.FLAT
slopeByMinute <= 2 -> GlucoseValue.TrendArrow.FORTY_FIVE_UP
slopeByMinute <= 3.5 -> GlucoseValue.TrendArrow.SINGLE_UP
slopeByMinute <= 40 -> GlucoseValue.TrendArrow.DOUBLE_UP
else -> GlucoseValue.TrendArrow.NONE
slopeByMinute <= -3.5 -> DOUBLE_DOWN
slopeByMinute <= -2 -> SINGLE_DOWN
slopeByMinute <= -1 -> FORTY_FIVE_DOWN
slopeByMinute <= 1 -> FLAT
slopeByMinute <= 2 -> FORTY_FIVE_UP
slopeByMinute <= 3.5 -> SINGLE_UP
slopeByMinute <= 40 -> DOUBLE_UP
else -> NONE
}
}
}

View file

@ -112,6 +112,7 @@ public class TimeListEdit {
float factor = layout.getContext().getResources().getDisplayMetrics().density;
finalAdd = new ImageView(context);
finalAdd.setImageResource(R.drawable.ic_add);
finalAdd.setContentDescription(layout.getContext().getResources().getString(R.string.addnew));
LinearLayout.LayoutParams illp = new LinearLayout.LayoutParams((int) (35d * factor), (int) (35 * factor));
illp.setMargins(0, 25, 0, 25); // llp.setMargins(left, top, right, bottom);
illp.gravity = Gravity.CENTER;

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/cb_backgroud_bg" />
<item android:drawable="@drawable/cb_background_bg" />
</selector>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/cb_backgroud_cob" />
<item android:drawable="@drawable/cb_background_cob" />
</selector>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/cb_backgroud_iob" />
<item android:drawable="@drawable/cb_background_iob" />
</selector>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="@drawable/cb_backgroud_trend" />
<item android:drawable="@drawable/cb_background_trend" />
</selector>

View file

@ -124,6 +124,7 @@
android:focusable="true">
<TextView
android:id="@+id/cannula_or_patch"
android:layout_width="wrap_content"
android:layout_height="25dp"
android:gravity="center_vertical"

View file

@ -126,6 +126,7 @@
android:layout_weight="0.5"
android:drawableTop="@drawable/ic_quick_wizard"
android:text="@string/quickwizard"
android:hint="@string/quickwizard"
android:textColor="@color/colorQuickWizardButton"
android:textSize="10sp"
tools:ignore="SmallSp" />

View file

@ -39,6 +39,7 @@
android:gravity="center_vertical|center_horizontal"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:hint="active profile"
android:text="Profile"
android:textAppearance="?android:attr/textAppearanceSmall"
tools:ignore="HardcodedText" />
@ -52,6 +53,7 @@
android:gravity="center_vertical|center_horizontal"
android:paddingTop="6dp"
android:paddingBottom="6dp"
android:hint="temp target"
android:text="@string/notavailable"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@color/mdtp_white"

View file

@ -14,7 +14,8 @@
<com.jjoe64.graphview.GraphView
android:id="@+id/bg_graph"
android:layout_width="wrap_content"
android:layout_height="200dp" />
android:layout_height="200dp"
android:contentDescription="@string/a11y_graph"/>
<ImageButton
android:id="@+id/chart_menu_button"

View file

@ -25,7 +25,7 @@
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="Blood glucose quality icon"
android:contentDescription="@string/a11y_bg_quality"
tools:ignore="HardcodedText" />
<TextView
@ -52,7 +52,8 @@
app:layout_constraintEnd_toStartOf="@+id/deltas_layout"
app:layout_constraintStart_toEndOf="@+id/delta_large"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="UseCompoundDrawables">
tools:ignore="UseCompoundDrawables"
android:focusable="true">
<ImageView
android:id="@+id/arrow"
@ -87,7 +88,8 @@
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="horizontal"
android:focusable="true">
<TextView
android:layout_width="wrap_content"
@ -95,6 +97,7 @@
android:layout_gravity="end"
android:textAlignment="textEnd"
android:text="Δ: "
android:contentDescription="last delta"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:ignore="HardcodedText" />
@ -113,7 +116,8 @@
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="horizontal"
android:focusable="true">
<TextView
android:layout_width="wrap_content"
@ -121,6 +125,7 @@
android:layout_gravity="end"
android:textAlignment="textEnd"
android:text="15m Δ: "
android:contentDescription="15 minutes delta"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:ignore="HardcodedText" />
@ -139,7 +144,8 @@
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
android:orientation="horizontal"
android:focusable="true">
<TextView
android:layout_width="wrap_content"
@ -147,6 +153,7 @@
android:layout_gravity="end"
android:textAlignment="textEnd"
android:text="40m Δ: "
android:contentDescription="40 minutes delta"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:ignore="HardcodedText" />
@ -185,7 +192,7 @@
android:layout_marginBottom="-4dp"
android:visibility="gone"
app:srcCompat="@drawable/ic_loop_closed"
android:contentDescription="@string/closedloop" />
android:contentDescription="@string/apsmode_title" />
<TextView
android:id="@+id/aps_mode_text"
@ -282,7 +289,8 @@
app:layout_constraintEnd_toStartOf="@+id/basal_layout"
app:layout_constraintStart_toEndOf="@+id/iob_layout"
app:layout_constraintTop_toTopOf="@+id/iob_layout"
tools:ignore="UseCompoundDrawables">
tools:ignore="UseCompoundDrawables"
android:focusable="true">
<ImageView
android:id="@+id/carbs_icon"
@ -377,7 +385,8 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/extended_layout"
app:layout_constraintTop_toTopOf="@+id/iob_layout"
tools:ignore="UseCompoundDrawables">
tools:ignore="UseCompoundDrawables"
android:focusable="true">
<ImageView
android:id="@+id/sensitivity_icon"
@ -385,7 +394,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
app:srcCompat="@drawable/ic_swap_vert_black_48dp_green"
android:contentDescription="@string/autosenslabel" />
android:contentDescription="@string/a11y_autosenslabel" />
<TextView
android:id="@+id/sensitivity"

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<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:id="@+id/status_lights"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -11,101 +12,117 @@
android:paddingTop="4dp"
android:paddingBottom="4dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="true"
android:gravity="center_horizontal">
<ImageView
android:id="@+id/cannula_or_patch"
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleX = "2"
android:scaleY = "2"
android:gravity="center_vertical"
android:scaleType="centerInside"
app:srcCompat="@drawable/ic_cp_age_cannula"
android:contentDescription="@string/statuslights_cannula_age" />
android:layout_width="38dp"
android:layout_height="fill_parent"
android:contentDescription="@string/statuslights_cannula_age"
android:scaleX="2"
android:scaleY="2"
app:srcCompat="@drawable/ic_cp_age_cannula" />
<TextView
android:id="@+id/cannula_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="1dp"
android:paddingEnd="2dp"
android:textSize="14sp" />
android:lines="1"
tools:text="1d12h" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:focusable="true"
android:gravity="center_horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:scaleType="centerInside"
android:scaleX="1.6"
android:scaleY="1.6"
app:srcCompat="@drawable/ic_cp_age_insulin"
android:contentDescription="@string/insulin_label" />
android:layout_width="26dp"
android:layout_height="fill_parent"
android:contentDescription="@string/a11y_insulin_label"
android:scaleX="1.7"
android:scaleY="1.7"
app:srcCompat="@drawable/ic_cp_age_insulin" />
<TextView
android:id="@+id/insulin_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="1dp"
android:paddingEnd="2dp"
android:textSize="14sp" />
android:layout_height="fill_parent"
android:lines="1"
tools:text="12h" />
<TextView
android:id="@+id/reservoir_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textSize="14sp" />
android:lines="1"
android:paddingStart="2dp"
tools:text="50+U" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:focusable="true"
android:gravity="center_horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:scaleType="centerInside"
android:scaleX="2"
android:scaleY="2"
app:srcCompat="@drawable/ic_cp_age_sensor"
android:contentDescription="@string/careportal_sensor_label" />
android:layout_width="28dp"
android:layout_height="fill_parent"
android:contentDescription="@string/careportal_sensor_label"
android:scaleX="1.6"
android:scaleY="1.6"
app:srcCompat="@drawable/ic_cp_age_sensor" />
<TextView
android:id="@+id/sensor_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="1dp"
android:paddingEnd="2dp"
android:textSize="14sp" />
android:lines="1"
tools:text="1d12h" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"
android:focusable="true"
android:gravity="center_horizontal">
<ImageView
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_vertical"
android:scaleType="centerInside"
android:scaleX="2"
android:scaleY="2"
app:srcCompat="@drawable/ic_cp_age_battery"
android:contentDescription="@string/battery_label" />
android:layout_width="32dp"
android:layout_height="wrap_content"
android:contentDescription="@string/battery_label"
android:scaleX="1.8"
android:scaleY="1.8"
app:srcCompat="@drawable/ic_cp_age_battery" />
<TextView
android:id="@+id/pb_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="1dp"
android:paddingEnd="1dp"
android:textSize="14sp" />
android:layout_height="fill_parent"
android:lines="1"
tools:text="-" />
<TextView
android:id="@+id/battery_level"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingStart="1dp"
android:paddingEnd="2dp"
android:textSize="14sp" />
android:layout_height="fill_parent"
android:lines="1"
android:paddingStart="2dp"
tools:text="100%" />
</LinearLayout>
</LinearLayout>

View file

@ -38,6 +38,7 @@
android:layout_height="35dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:contentDescription="@string/addnew_above"
app:srcCompat="@drawable/ic_add" />
<ImageView
@ -46,5 +47,6 @@
android:layout_height="35dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:contentDescription="@string/remove_label"
app:srcCompat="@drawable/ic_remove" />
</LinearLayout>

View file

@ -38,6 +38,7 @@
android:layout_height="35dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:contentDescription="@string/addnew_above"
app:srcCompat="@drawable/ic_add" />
<ImageView
@ -46,5 +47,6 @@
android:layout_height="35dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="15dp"
android:contentDescription="@string/remove_label"
app:srcCompat="@drawable/ic_remove" />
</LinearLayout>

View file

@ -169,7 +169,6 @@
<string name="configbuilder_bgsource_description">Where should AndroidAPS gain it\'s data from?</string>
<string name="xdrip">xDrip+</string>
<string name="apsmode_title">APS Mode</string>
<string name="closedloop">Closed Loop</string>
<string name="openloop">Open Loop</string>
<string name="lowglucosesuspend">Low Glucose Suspend</string>
@ -1141,27 +1140,29 @@
<string name="key_last_processed_glunovo_timestamp" translatable="false">last_processed_glunovo_timestamp</string>
<string name="identification">Identification (email, FB or Discord nick etc)</string>
<string name="identification_not_set">Identification not set in dev mode</string>
<string name="a11y_high">heigh</string>
<string name="a11y_inrange">in range</string>
<string name="a11y_low">low</string>
<string name="a11y_arrow_double_down">down fast</string>
<string name="a11y_arrow_single_down">down</string>
<string name="a11y_arrow_forty_five_down">down trending</string>
<string name="a11y_arrow_flat">flat</string>
<string name="a11y_arrow_forty_five_up">up trending</string>
<string name="a11y_arrow_single_up">up</string>
<string name="a11y_arrow_double_up">up fast</string>
<string name="a11y_arrow_none">none</string>
<string name="a11y_arrow_unknown">unknown</string>
<string name="a11y_graph">graph</string>
<string name="a11y_bg_quality">Blood glucose quality</string>
<string name="a11_bg_quality_recalculated">recalculated</string>
<string name="a11_bg_quality_doubles">double entries</string>
<string name="a11y_insulin_label">insulin</string>
<string name="a11y_dialog">dialog</string>
<string name="a11y_current_bg">current blood glucode</string>
<string name="a11y_current_bg">current blood glucose</string>
<string name="a11_correction_percentage">correct outcome with %</string>
<string name="a11_correction_units">correct outcome with units</string>
<string name="not_available_full">Not available</string>
<string name="a11y_high">high</string>
<string name="a11y_inrange">in range</string>
<string name="a11y_low">low</string>
<string name="a11y_arrow_double_down">falling rapidly</string>
<string name="a11y_arrow_single_down">falling</string>
<string name="a11y_arrow_forty_five_down">falling slowly</string>
<string name="a11y_arrow_flat">stable</string>
<string name="a11y_arrow_forty_five_up">rising slowly</string>
<string name="a11y_arrow_single_up">rising</string>
<string name="a11y_arrow_double_up">rising rapidly</string>
<string name="a11y_arrow_none">none</string>
<string name="a11y_arrow_unknown">unknown</string>
<string name="a11y_graph">graph</string>
<string name="a11y_bg_quality">blood glucose quality</string>
<string name="a11y_bg_quality_recalculated">recalculated</string>
<string name="a11y_bg_quality_doubles">double entries</string>
<string name="a11y_insulin_label">insulin</string>
<string name="a11y_blood_glucose">blood glucose</string>
<string name="a11y_bg_outdated">outdated</string>
</resources>

View file

@ -83,6 +83,7 @@
<string name="wifissidcompared">WiFi SSID %1$s %2$s</string>
<string name="autosenscompared">Autosens %1$s %2$s %%</string>
<string name="autosenslabel">Autosens %</string>
<string name="a11y_autosenslabel">Auto sens</string>
<string name="deltacompared">%3$s %1$s %2$s</string>
<string name="deltalabel">BG difference</string>
<string name="deltalabel_u">BG difference [%1$s]</string>

View file

@ -156,6 +156,12 @@ class DateUtil @Inject constructor(private val context: Context) {
return (if (mins > 0) "+" else "") + mins
}
fun minAgoLong(rh: ResourceHelper, time: Long?): String {
if (time == null) return ""
val mins = ((now() - time) / 1000 / 60).toInt()
return rh.gs(R.string.minago_long, mins)
}
fun hourAgo(time: Long, rh: ResourceHelper): String {
val hours = (now() - time) / 1000.0 / 60 / 60
return rh.gs(R.string.hoursago, hours)

View file

@ -173,6 +173,7 @@
<string name="notes_label">Notes</string>
<string name="remove_button">Remove</string>
<string name="addnew">Add new</string>
<string name="addnew_above">Add new above</string>
<string name="wrong_pump_data">Data is coming from different pump. Change pump driver to reset pump state.</string>
<!-- Constraints-->
@ -199,6 +200,7 @@
<!-- DateUtil-->
<string name="minago">%1$d m ago</string>
<string name="minago_long">%1$d minutes ago</string>
<string name="hoursago">%1$.1f h ago</string>
<string name="shorthour">h</string>
<string name="days">days</string>