commit
a2411bb512
4034 changed files with 216960 additions and 110473 deletions
73
.circleci/config.yml
Normal file
73
.circleci/config.yml
Normal file
|
@ -0,0 +1,73 @@
|
|||
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
||||
# See: https://circleci.com/docs/2.0/configuration-reference
|
||||
version: 2.1
|
||||
|
||||
# Orbs are reusable packages of CircleCI configuration that you may share across projects, enabling you to create encapsulated, parameterized commands, jobs, and executors that can be used across multiple projects.
|
||||
orbs:
|
||||
android: circleci/android@1.0.3
|
||||
codecov: codecov/codecov@1.2.0
|
||||
|
||||
jobs:
|
||||
# Below is the definition of your job to build and test your app, you can rename and customize it as you want.
|
||||
build-and-test:
|
||||
# These next lines define the Android machine image executor: https://circleci.com/docs/2.0/executor-types/
|
||||
executor:
|
||||
name: android/android-machine
|
||||
|
||||
steps:
|
||||
# Checkout the code as the first step.
|
||||
- checkout
|
||||
|
||||
# The next step will run the unit tests
|
||||
- android/run-tests:
|
||||
test-command: ./gradlew -Pcoverage -PfirebaseDisable testFullDebugUnitTest jacocoTestFullDebugUnitTestReport
|
||||
|
||||
# Then start the emulator and run the Instrumentation tests!
|
||||
# - android/start-emulator-and-run-tests:
|
||||
# test-command: ./gradlew connectedDebugAndroidTest
|
||||
# system-image: system-images;android-25;google_apis;x86
|
||||
|
||||
# And finally run the release build
|
||||
# - run:
|
||||
# name: Assemble release build
|
||||
# command: |
|
||||
# ./gradlew assembleRelease
|
||||
- codecov/upload:
|
||||
file: './app/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './automation/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './combo/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './core/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './dana/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './danar/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './danars/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './database/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './insight/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './medtronic/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './omnipod-common/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './omnipod-dash/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './omnipod-eros/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './rileylink/build/jacoco/jacoco.xml'
|
||||
- codecov/upload:
|
||||
file: './wear/build/jacoco/jacoco.xml'
|
||||
|
||||
workflows:
|
||||
# Below is the definition of your workflow.
|
||||
# Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above.
|
||||
# CircleCI will run this workflow on every commit.
|
||||
# For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows
|
||||
dotests:
|
||||
jobs:
|
||||
- build-and-test
|
5
.editorconfig
Normal file
5
.editorconfig
Normal file
|
@ -0,0 +1,5 @@
|
|||
root = true
|
||||
|
||||
|
||||
[*{kt,kts}]
|
||||
disabled_rules=no-wildcard-imports
|
19
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/custom.md
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
name: Custom issue template
|
||||
about: Describe this issue template's purpose here.
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Reporting bugs
|
||||
--------------
|
||||
- **Note the precise time the problem occurred** and describe the circumstances and steps that caused
|
||||
the problem
|
||||
- Note the Build version (found in the About dialog in the app, when pressing the three dots in the
|
||||
upper-right corner).
|
||||
- Obtain the app's log files, which can be found on the phone in
|
||||
_/storage/emulated/0/Android/data/info.nightscout.androidaps/_
|
||||
See https://androidaps.readthedocs.io/en/latest/Usage/Accessing-logfiles.html
|
||||
- Open an issue at https://github.com/nightscout/AndroidAPS/issues/new
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,15 +2,15 @@
|
|||
.gradle
|
||||
/local.properties
|
||||
.DS_Store
|
||||
*/jacoco.exec
|
||||
/build
|
||||
/captures
|
||||
*.apk
|
||||
build/
|
||||
!.idea/dictionaries/project-dictionary.xml
|
||||
.idea/*
|
||||
!.idea/codeStyles/
|
||||
full/
|
||||
debug/
|
||||
release/
|
||||
app/com.crashlytics.settings.json
|
||||
app/session_analytics.tap
|
||||
.project
|
||||
|
|
|
@ -1,27 +1,13 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="AUTODETECT_INDENTS" value="false" />
|
||||
<option name="WRAP_WHEN_TYPING_REACHES_RIGHT_MARGIN" value="true" />
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="java.util" alias="false" withSubpackages="false" />
|
||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
<package name="io.ktor" alias="false" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="PACKAGES_IMPORT_LAYOUT">
|
||||
<value>
|
||||
<package name="" alias="false" withSubpackages="true" />
|
||||
<package name="java" alias="false" withSubpackages="true" />
|
||||
<package name="javax" alias="false" withSubpackages="true" />
|
||||
<package name="kotlin" alias="false" withSubpackages="true" />
|
||||
<package name="" alias="true" withSubpackages="true" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="6" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="6" />
|
||||
<option name="BLANK_LINES_AROUND_BLOCK_WHEN_BRANCHES" value="1" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="METHOD_ANNOTATION_WRAP" value="0" />
|
||||
|
@ -140,14 +126,22 @@
|
|||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="RIGHT_MARGIN" value="200" />
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" />
|
||||
<option name="BLANK_LINES_AFTER_CLASS_HEADER" value="1" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
|
||||
<option name="ASSIGNMENT_WRAP" value="5" />
|
||||
<option name="METHOD_ANNOTATION_WRAP" value="5" />
|
||||
<option name="FIELD_ANNOTATION_WRAP" value="0" />
|
||||
<option name="CLASS_ANNOTATION_WRAP" value="1" />
|
||||
<option name="FIELD_ANNOTATION_WRAP" value="1" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="1" />
|
||||
<option name="VARIABLE_ANNOTATION_WRAP" value="1" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="5" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
|
|
108
.idea/dictionaries/project_dictionary.xml
Normal file
108
.idea/dictionaries/project_dictionary.xml
Normal file
|
@ -0,0 +1,108 @@
|
|||
<component name="ProjectDictionaryState">
|
||||
<dictionary name="project-dictionary">
|
||||
<words>
|
||||
<w>aaps</w>
|
||||
<w>abcdef</w>
|
||||
<w>acked</w>
|
||||
<w>actionstring</w>
|
||||
<w>allowednumbers</w>
|
||||
<w>androidaps</w>
|
||||
<w>autosens</w>
|
||||
<w>autosensdata</w>
|
||||
<w>autosense</w>
|
||||
<w>bage</w>
|
||||
<w>basaliob</w>
|
||||
<w>basals</w>
|
||||
<w>bgcheck</w>
|
||||
<w>bgsource</w>
|
||||
<w>boluscalc</w>
|
||||
<w>bolusing</w>
|
||||
<w>carb</w>
|
||||
<w>carbratio</w>
|
||||
<w>carbs</w>
|
||||
<w>carbsreq</w>
|
||||
<w>careportal</w>
|
||||
<w>cellnovo</w>
|
||||
<w>crashlytics</w>
|
||||
<w>danar</w>
|
||||
<w>danars</w>
|
||||
<w>dataset</w>
|
||||
<w>datasets</w>
|
||||
<w>dexcom</w>
|
||||
<w>dexdrip</w>
|
||||
<w>enteredby</w>
|
||||
<w>enteredinsulin</w>
|
||||
<w>eveningoutpost</w>
|
||||
<w>eversense</w>
|
||||
<w>extendedbolus</w>
|
||||
<w>fileprovider</w>
|
||||
<w>firebase</w>
|
||||
<w>glimp</w>
|
||||
<w>gson</w>
|
||||
<w>hmac</w>
|
||||
<w>iage</w>
|
||||
<w>insulet</w>
|
||||
<w>iobtotal</w>
|
||||
<w>libre</w>
|
||||
<w>listdelimiter</w>
|
||||
<w>localprofile</w>
|
||||
<w>medtronic</w>
|
||||
<w>mgdl</w>
|
||||
<w>mmol</w>
|
||||
<w>motol</w>
|
||||
<w>multiwave</w>
|
||||
<w>netinsulin</w>
|
||||
<w>netratio</w>
|
||||
<w>nightscout</w>
|
||||
<w>notif</w>
|
||||
<w>nsclient</w>
|
||||
<w>okcancel</w>
|
||||
<w>omnipod</w>
|
||||
<w>openaps</w>
|
||||
<w>openhumans</w>
|
||||
<w>oref</w>
|
||||
<w>otpauth</w>
|
||||
<w>passcode</w>
|
||||
<w>pdus</w>
|
||||
<w>philoul</w>
|
||||
<w>poctech</w>
|
||||
<w>pred</w>
|
||||
<w>profileswitch</w>
|
||||
<w>pumpbtcomm</w>
|
||||
<w>quickwizard</w>
|
||||
<w>readstatus</w>
|
||||
<w>realduration</w>
|
||||
<w>refresheventsfromnightscout</w>
|
||||
<w>rileylink</w>
|
||||
<w>roboelectric</w>
|
||||
<w>sgvs</w>
|
||||
<w>sitechange</w>
|
||||
<w>smscommunicator</w>
|
||||
<w>sntp</w>
|
||||
<w>sooil</w>
|
||||
<w>soundid</w>
|
||||
<w>splitted</w>
|
||||
<w>ssid</w>
|
||||
<w>superbolus</w>
|
||||
<w>targethigh</w>
|
||||
<w>targetlow</w>
|
||||
<w>tbrs</w>
|
||||
<w>tdds</w>
|
||||
<w>tempbasal</w>
|
||||
<w>tempbasals</w>
|
||||
<w>temptarget</w>
|
||||
<w>textl</w>
|
||||
<w>tidepool</w>
|
||||
<w>timeshift</w>
|
||||
<w>tirs</w>
|
||||
<w>totp</w>
|
||||
<w>uart</w>
|
||||
<w>wizzardpage</w>
|
||||
<w>xdrip</w>
|
||||
<w>xstream</w>
|
||||
<w>ypso</w>
|
||||
<w>ypsomed</w>
|
||||
<w>ypsopump</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
|
@ -1,5 +1,5 @@
|
|||
language: android
|
||||
jdk: oraclejdk8
|
||||
jdk: openjdk11
|
||||
dist: trusty
|
||||
env:
|
||||
matrix:
|
||||
|
|
122
app/build.gradle
122
app/build.gradle
|
@ -1,33 +1,24 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url "https://plugins.gradle.org/m2/" } // jacoco 0.2
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//classpath 'com.dicedmelon.gradle:jacoco-android:0.1.4'
|
||||
classpath 'com.hiya:jacoco-android:0.2'
|
||||
}
|
||||
}
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-allopen'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
//apply plugin: 'jacoco-android'
|
||||
apply plugin: 'com.hiya.jacoco-android'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.3"
|
||||
}
|
||||
apply from: "${project.rootDir}/gradle/android_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/gradle/jacoco_global.gradle"
|
||||
|
||||
repositories {
|
||||
jcenter { url "https://jcenter.bintray.com/" }
|
||||
mavenCentral()
|
||||
google()
|
||||
}
|
||||
|
||||
allOpen {
|
||||
// allows mocking for classes w/o directly opening them for release builds
|
||||
annotation 'info.nightscout.androidaps.annotations.OpenForTesting'
|
||||
}
|
||||
|
||||
def generateGitBuild = { ->
|
||||
StringBuilder stringBuilder = new StringBuilder()
|
||||
try {
|
||||
|
@ -108,57 +99,27 @@ def allCommitted = { ->
|
|||
|
||||
tasks.matching { it instanceof Test }.all {
|
||||
testLogging.events = ["failed", "skipped", "started"]
|
||||
// testLogging.events = ["failed", "skipped", "started", "standard_out"] use to display stdout in travis
|
||||
testLogging.exceptionFormat = "full"
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
ndkVersion "21.1.6352462"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 28
|
||||
multiDexEnabled true
|
||||
versionCode 1500
|
||||
version "2.8.2.1"
|
||||
version "3.0.0"
|
||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
|
||||
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
|
||||
buildConfigField "String", "HEAD", '"' + generateGitBuild() + '"'
|
||||
buildConfigField "String", "COMMITTED", '"' + allCommitted() + '"'
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
// if you change minSdkVersion to less than 11, you need to change executeTask for wear
|
||||
|
||||
ndk {
|
||||
moduleName "BleCommandUtil"
|
||||
}
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
disable 'MissingTranslation'
|
||||
disable 'ExtraTranslation'
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
debug {
|
||||
testCoverageEnabled(project.hasProperty('coverage'))
|
||||
}
|
||||
firebaseDisable {
|
||||
System.setProperty("disableFirebase", "true")
|
||||
ext.enableCrashlytics = false
|
||||
}
|
||||
}
|
||||
productFlavors {
|
||||
|
||||
flavorDimensions "standard"
|
||||
productFlavors {
|
||||
full {
|
||||
applicationId "info.nightscout.androidaps"
|
||||
dimension "standard"
|
||||
|
@ -200,28 +161,8 @@ android {
|
|||
]
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
testOptions {
|
||||
unitTests {
|
||||
returnDefaultValues = true
|
||||
includeAndroidResources = true
|
||||
|
||||
all {
|
||||
maxParallelForks = 10
|
||||
forkEvery = 20
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useLibrary "org.apache.http.legacy"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
@ -235,51 +176,40 @@ allprojects {
|
|||
dependencies {
|
||||
wearApp project(':wear')
|
||||
|
||||
implementation project(':shared')
|
||||
implementation project(':core')
|
||||
implementation project(':automation')
|
||||
implementation project(':combo')
|
||||
implementation project(':database')
|
||||
implementation project(':dana')
|
||||
implementation project(':danars')
|
||||
implementation project(':danar')
|
||||
implementation project(':insight')
|
||||
implementation project(':pump-common')
|
||||
implementation project(':rileylink')
|
||||
implementation project(':medtronic')
|
||||
implementation project(':omnipod')
|
||||
implementation project(':omnipod-common')
|
||||
implementation project(':omnipod-eros')
|
||||
implementation project(':omnipod-dash')
|
||||
implementation project(':diaconn')
|
||||
implementation project(':openhumans')
|
||||
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
|
||||
testImplementation "junit:junit:$junit_version"
|
||||
testImplementation 'org.json:json:20200518'
|
||||
testImplementation "org.mockito:mockito-core:${mockitoVersion}"
|
||||
testImplementation "org.powermock:powermock-api-mockito2:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4-rule-agent:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4-rule:${powermockVersion}"
|
||||
testImplementation "org.powermock:powermock-module-junit4:${powermockVersion}"
|
||||
testImplementation 'joda-time:joda-time:2.10.6'
|
||||
testImplementation('com.google.truth:truth:1.0.1') {
|
||||
exclude group: "com.google.guava", module: "guava"
|
||||
exclude group: "com.google.code.findbugs", module: "jsr305"
|
||||
}
|
||||
testImplementation "org.skyscreamer:jsonassert:1.5.0"
|
||||
testImplementation "org.hamcrest:hamcrest-all:1.3"
|
||||
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0-alpha03'
|
||||
androidTestImplementation "androidx.test.ext:junit:$androidx_junit"
|
||||
androidTestImplementation "androidx.test:rules:$androidx_rules"
|
||||
androidTestImplementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
/* Dagger2 - We are going to use dagger.android which includes
|
||||
* support for Activity and fragment injection so we need to include
|
||||
* the following dependencies */
|
||||
|
||||
|
||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"
|
||||
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
|
||||
|
||||
/* Dagger2 - default dependency */
|
||||
kapt "com.google.dagger:dagger-compiler:$dagger_version"
|
||||
|
||||
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
|
||||
}
|
||||
|
||||
apply from: "${project.rootDir}/gradle/test_dependencies.gradle"
|
||||
|
||||
|
||||
/*
|
||||
// Run 'adb' shell command to clear application data of main app for 'debug' variant
|
||||
task clearMainAppData(type: Exec) {
|
||||
|
|
BIN
app/jacoco.exec
BIN
app/jacoco.exec
Binary file not shown.
Binary file not shown.
BIN
app/libs/wearpreferenceactivity-0.5.0.aar
Normal file
BIN
app/libs/wearpreferenceactivity-0.5.0.aar
Normal file
Binary file not shown.
|
@ -1,40 +1,13 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import android.os.SystemClock
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONObject
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import javax.inject.Inject
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RealPumpTest {
|
||||
|
||||
/*
|
||||
companion object {
|
||||
const val R_PASSWORD = 1234
|
||||
const val R_SERIAL = "PBB00013LR_P"
|
||||
|
@ -89,7 +62,7 @@ class RealPumpTest {
|
|||
localProfilePlugin.numOfProfiles = 0
|
||||
val singleProfile = LocalProfilePlugin.SingleProfile().copyFrom(localProfilePlugin.rawProfile, profile, "TestProfile")
|
||||
localProfilePlugin.addProfile(singleProfile)
|
||||
val profileSwitch = profileFunction.prepareProfileSwitch(localProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, DateUtil.now())
|
||||
val profileSwitch = profileFunction.prepareProfileSwitch(localProfilePlugin.createProfileStore(), "TestProfile", 0, 100, 0, dateUtil._now())
|
||||
treatmentsPlugin.addToHistoryProfileSwitch(profileSwitch)
|
||||
// Insulin
|
||||
configBuilderPlugin.performPluginSwitch(insulinOrefUltraRapidActingPlugin, true, PluginType.INSULIN)
|
||||
|
@ -125,4 +98,5 @@ class RealPumpTest {
|
|||
SystemClock.sleep(1000)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
|
@ -1,48 +1,13 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import android.os.SystemClock
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.test.espresso.Espresso.onData
|
||||
import androidx.test.espresso.Espresso.onView
|
||||
import androidx.test.espresso.action.ViewActions
|
||||
import androidx.test.espresso.action.ViewActions.click
|
||||
import androidx.test.espresso.action.ViewActions.scrollTo
|
||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withClassName
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withTagValue
|
||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.LargeTest
|
||||
import androidx.test.rule.ActivityTestRule
|
||||
import androidx.test.rule.GrantPermissionRule
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.source.RandomBgPlugin
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
||||
import org.hamcrest.CoreMatchers.allOf
|
||||
import org.hamcrest.Description
|
||||
import org.hamcrest.Matcher
|
||||
import org.hamcrest.Matchers
|
||||
import org.hamcrest.TypeSafeMatcher
|
||||
import org.junit.Assert
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@LargeTest
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SetupWizardActivityTest {
|
||||
|
||||
/*
|
||||
@Rule
|
||||
@JvmField
|
||||
var mActivityTestRule = ActivityTestRule(SetupWizardActivity::class.java)
|
||||
|
@ -226,4 +191,5 @@ adb shell settings put global animator_duration_scale 0 &
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="info.nightscout.androidaps">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
@ -26,6 +27,7 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="com.dexcom.cgm.EXTERNAL_PERMISSION" />
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
|
||||
|
||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||
|
||||
|
@ -52,7 +54,8 @@
|
|||
android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc" />
|
||||
|
||||
<activity android:name=".MainActivity">
|
||||
<activity android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -60,7 +63,8 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".activities.PreferencesActivity" />
|
||||
<activity android:name=".plugins.general.overview.activities.QuickWizardListActivity">
|
||||
<activity android:name=".plugins.general.overview.activities.QuickWizardListActivity"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity" />
|
||||
|
||||
|
@ -68,15 +72,20 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".plugins.general.maintenance.activities.PrefImportListActivity" />
|
||||
<activity android:name=".historyBrowser.HistoryBrowseActivity" />
|
||||
<activity android:name=".activities.HistoryBrowseActivity" />
|
||||
<activity android:name=".activities.TreatmentsActivity" />
|
||||
<activity android:name=".activities.SurveyActivity" />
|
||||
<activity android:name=".activities.ProfileHelperActivity"
|
||||
android:theme="@style/ProfileHelperAppTheme" />
|
||||
<activity android:name=".activities.StatsActivity" />
|
||||
<activity
|
||||
android:name="com.google.firebase.auth.internal.FederatedSignInActivity"
|
||||
tools:replace="android:launchMode"
|
||||
android:launchMode="standard" />
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:permission="com.google.firebase.auth.api.gms.permission.LAUNCH_FEDERATED_SIGN_IN"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
tools:replace="android:launchMode" />
|
||||
|
||||
<!-- Receive new BG readings from other local apps -->
|
||||
<receiver
|
||||
|
@ -110,11 +119,11 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Receiver keepalive, scheduled every 30 min -->
|
||||
<!-- Receiver keep alive, scheduled every 30 min -->
|
||||
<receiver android:name=".receivers.KeepAliveReceiver" />
|
||||
|
||||
<!-- Receive ignore 5m, 15m, 30m requests for carb notifications -->
|
||||
<receiver android:name=".plugins.aps.loop.CarbSuggestionReceiver"></receiver>
|
||||
<receiver android:name=".plugins.aps.loop.CarbSuggestionReceiver" />
|
||||
|
||||
<!-- Auto start -->
|
||||
<receiver
|
||||
|
@ -136,13 +145,6 @@
|
|||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
|
||||
<!-- Service processing incomming data -->
|
||||
<service
|
||||
android:name=".services.DataService"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".services.LocationService"
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".plugins.general.wear.wearintegration.WatchUpdaterService"
|
||||
android:exported="true">
|
||||
|
@ -219,8 +221,6 @@
|
|||
android:exported="false" />
|
||||
|
||||
<service android:name=".plugins.general.persistentNotification.DummyService" />
|
||||
<service android:name=".plugins.pump.insight.connection_service.InsightConnectionService" />
|
||||
<service android:name=".plugins.pump.insight.InsightAlertService" />
|
||||
|
||||
<meta-data
|
||||
android:name="io.fabric.ApiKey"
|
||||
|
@ -236,20 +236,6 @@
|
|||
android:name=".activities.SingleFragmentActivity"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity android:name=".plugins.general.maintenance.activities.LogSettingActivity" />
|
||||
<activity
|
||||
android:name=".plugins.pump.insight.activities.InsightPairingActivity"
|
||||
android:label="@string/insight_pairing"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity
|
||||
android:name=".plugins.pump.insight.activities.InsightAlertActivity"
|
||||
android:label="@string/pump_alert"
|
||||
android:excludeFromRecents="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/InsightAlertDialog" />
|
||||
<activity
|
||||
android:name=".plugins.pump.insight.activities.InsightPairingInformationActivity"
|
||||
android:label="@string/pairing_information"
|
||||
android:theme="@style/AppTheme" />
|
||||
<activity android:name=".activities.RequestDexcomPermissionActivity" />
|
||||
<activity android:name=".plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity">
|
||||
<intent-filter>
|
||||
|
@ -259,27 +245,6 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Medtronic service and activities -->
|
||||
<service
|
||||
android:name=".plugins.pump.medtronic.service.RileyLinkMedtronicService"
|
||||
android:enabled="true"
|
||||
android:exported="true" />
|
||||
|
||||
<activity android:name=".plugins.pump.medtronic.dialog.MedtronicHistoryActivity" />
|
||||
<activity android:name=".plugins.general.openhumans.OpenHumansLoginActivity"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="setup-openhumans"
|
||||
android:scheme="androidaps" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
</application>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<configuration>
|
||||
<!-- Create a file appender for a log in the application's data directory -->
|
||||
<property name="EXT_FILES_DIR" scope="context"
|
||||
value="${EXT_DIR:-/sdcard}/Android/data/${PACKAGE_NAME}/files" />
|
||||
value="${EXT_DIR:-/sdcard}/AAPS/logs/${PACKAGE_NAME}" />
|
||||
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<file>${EXT_FILES_DIR}/AndroidAPS.log</file>
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
|
|
|
@ -4,4 +4,7 @@
|
|||
55:5D:70:C9:BE:10:41:7E:4B:01:A9:C4:C6:44:4A:F8:69:71:35:25:ED:95:23:16:C7:15:E8:EB:C6:08:FC:B1
|
||||
# àqΣnΖ`ZϼγwÛ/τàΒϳ9Φ'$ΑϵžλUΛ`ÆÌΣЃA
|
||||
E0:71:A3:6E:96:60:5A:FC:B3:77:DB:2F:C4:E0:92:F3:39:A6:27:24:91:F5:7E:BB:55:9B:60:C6:CC:A3:03:41
|
||||
# 2ΙšÄΠΒϨÒÇeЄtЄЗž-*Ж*ZcHijЊÄœ<|x"Ε
|
||||
32:99:61:C4:A0:92:E8:D2:C7:65:04:74:04:17:7E:2D:2A:16:2A:5A:63:48:69:6A:0A:C4:53:3C:7C:78:22:95
|
||||
# mςRr¡ЇζΛLφK&ĐΨ5CnЎϴPDñЍŒkϼ{ΨδwВb
|
||||
6D:C2:52:72:A1:07:B6:9B:4C:C6:4B:26:10:A8:35:43:6E:0E:F4:50:44:F1:0D:52:6B:FC:7B:A8:B4:77:12:62
|
|
@ -1,21 +0,0 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import android.os.Build
|
||||
import info.nightscout.androidaps.interfaces.ConfigInterface
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class Config @Inject constructor() : ConfigInterface {
|
||||
|
||||
override val SUPPORTEDNSVERSION = 1002 // 0.10.00
|
||||
override val APS = BuildConfig.FLAVOR == "full"
|
||||
override val NSCLIENT = BuildConfig.FLAVOR == "nsclient" || BuildConfig.FLAVOR == "nsclient2"
|
||||
override val PUMPCONTROL = BuildConfig.FLAVOR == "pumpcontrol"
|
||||
override val PUMPDRIVERS = BuildConfig.FLAVOR == "full" || BuildConfig.FLAVOR == "pumpcontrol"
|
||||
override val FLAVOR = BuildConfig.FLAVOR
|
||||
override val VERSION_NAME = BuildConfig.VERSION_NAME
|
||||
|
||||
override val currentDeviceModelString =
|
||||
Build.MANUFACTURER + " " + Build.MODEL + " (" + Build.DEVICE + ")"
|
||||
}
|
|
@ -21,28 +21,23 @@ import android.widget.TextView
|
|||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.joanzapata.iconify.Iconify
|
||||
import com.joanzapata.iconify.fonts.FontAwesomeModule
|
||||
import dev.doubledot.doki.ui.DokiActivity
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.activities.PreferencesActivity
|
||||
import info.nightscout.androidaps.activities.ProfileHelperActivity
|
||||
import info.nightscout.androidaps.activities.SingleFragmentActivity
|
||||
import info.nightscout.androidaps.activities.StatsActivity
|
||||
import info.nightscout.androidaps.activities.*
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.ActivityMainBinding
|
||||
import info.nightscout.androidaps.events.EventAppExit
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.events.EventRebuildTabs
|
||||
import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils
|
||||
|
@ -56,12 +51,13 @@ import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
|||
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
|
||||
import info.nightscout.androidaps.utils.locale.LocaleHelper
|
||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
||||
import info.nightscout.androidaps.utils.resources.IconsProvider
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.tabs.TabPageAdapter
|
||||
import info.nightscout.androidaps.utils.ui.UIRunnable
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.system.exitProcess
|
||||
|
@ -70,26 +66,29 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var androidPermission: AndroidPermission
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var versionCheckerUtils: VersionCheckerUtils
|
||||
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var loop: Loop
|
||||
@Inject lateinit var nsSettingsStatus: NSSettingsStatus
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var protectionCheck: ProtectionCheck
|
||||
@Inject lateinit var iconsProvider: IconsProvider
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var signatureVerifierPlugin: SignatureVerifierPlugin
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
|
||||
private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
|
||||
private var pluginPreferencesMenuItem: MenuItem? = null
|
||||
private var menu: Menu? = null
|
||||
private var menuOpen = false
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
||||
|
@ -109,7 +108,7 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
// initialize screen wake lock
|
||||
processPreferenceChange(EventPreferenceChange(resourceHelper.gs(R.string.key_keep_screen_on)))
|
||||
processPreferenceChange(EventPreferenceChange(rh.gs(R.string.key_keep_screen_on)))
|
||||
binding.mainPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrollStateChanged(state: Int) {}
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
|
@ -120,34 +119,33 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
})
|
||||
|
||||
//Check here if loop plugin is disabled. Else check via constraints
|
||||
if (!loopPlugin.isEnabled(PluginType.LOOP)) versionCheckerUtils.triggerCheckVersion()
|
||||
if (!(loop as PluginBase).isEnabled()) versionCheckerUtils.triggerCheckVersion()
|
||||
setUserStats()
|
||||
setupViews()
|
||||
disposable.add(rxBus
|
||||
disposable += rxBus
|
||||
.toObservable(EventRebuildTabs::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
if (it.recreate) recreate()
|
||||
else setupViews()
|
||||
setWakeLock()
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
disposable += rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ processPreferenceChange(it) }, fabricPrivacy::logException)
|
||||
)
|
||||
if (!sp.getBoolean(R.string.key_setupwizard_processed, false) && !isRunningRealPumpTest()) {
|
||||
if (startWizard() && !isRunningRealPumpTest()) {
|
||||
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
|
||||
startActivity(Intent(this, SetupWizardActivity::class.java))
|
||||
})
|
||||
}
|
||||
androidPermission.notifyForStoragePermission(this)
|
||||
androidPermission.notifyForBatteryOptimizationPermission(this)
|
||||
androidPermission.notifyForLocationPermissions(this)
|
||||
if (!config.NSCLIENT) androidPermission.notifyForLocationPermissions(this)
|
||||
if (config.PUMPDRIVERS) {
|
||||
androidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin)
|
||||
androidPermission.notifyForSystemWindowPermissions(this)
|
||||
androidPermission.notifyForBtConnectPermission(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,12 +153,15 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
if (viewPager.currentItem >= 0) pluginPreferencesMenuItem?.isEnabled = (viewPager.adapter as TabPageAdapter).getPluginAt(viewPager.currentItem).preferencesId != -1
|
||||
}
|
||||
|
||||
private fun startWizard(): Boolean =
|
||||
!sp.getBoolean(R.string.key_setupwizard_processed, false)
|
||||
|
||||
override fun onPostCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
|
||||
super.onPostCreate(savedInstanceState, persistentState)
|
||||
actionBarDrawerToggle.syncState()
|
||||
}
|
||||
|
||||
public override fun onDestroy() {
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
disposable.clear()
|
||||
}
|
||||
|
@ -168,8 +169,8 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
override fun onResume() {
|
||||
super.onResume()
|
||||
protectionCheck.queryProtection(this, ProtectionCheck.Protection.APPLICATION, null,
|
||||
UIRunnable { OKDialog.show(this, "", resourceHelper.gs(R.string.authorizationfailed)) { finish() } },
|
||||
UIRunnable { OKDialog.show(this, "", resourceHelper.gs(R.string.authorizationfailed)) { finish() } }
|
||||
UIRunnable { OKDialog.show(this, "", rh.gs(R.string.authorizationfailed)) { finish() } },
|
||||
UIRunnable { OKDialog.show(this, "", rh.gs(R.string.authorizationfailed)) { finish() } }
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -179,8 +180,8 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun processPreferenceChange(ev: EventPreferenceChange) {
|
||||
if (ev.isChanged(resourceHelper, R.string.key_keep_screen_on)) setWakeLock()
|
||||
if (ev.isChanged(resourceHelper, R.string.key_skin)) recreate()
|
||||
if (ev.isChanged(rh, R.string.key_keep_screen_on)) setWakeLock()
|
||||
if (ev.isChanged(rh, R.string.key_skin)) recreate()
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
|
@ -224,8 +225,10 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
binding.tabsCompact.visibility = View.GONE
|
||||
val typedValue = TypedValue()
|
||||
if (theme.resolveAttribute(R.attr.actionBarSize, typedValue, true)) {
|
||||
binding.toolbar.layoutParams = LinearLayout.LayoutParams(Toolbar.LayoutParams.MATCH_PARENT,
|
||||
TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics))
|
||||
binding.toolbar.layoutParams = LinearLayout.LayoutParams(
|
||||
Toolbar.LayoutParams.MATCH_PARENT,
|
||||
TypedValue.complexToDimensionPixelSize(typedValue.data, resources.displayMetrics)
|
||||
)
|
||||
}
|
||||
TabLayoutMediator(binding.tabsNormal, binding.mainPager) { tab, position ->
|
||||
tab.text = (binding.mainPager.adapter as TabPageAdapter).getPluginAt(position).name
|
||||
|
@ -252,10 +255,25 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
private fun setPluginPreferenceMenuName() {
|
||||
if (binding.mainPager.currentItem >= 0) {
|
||||
val plugin = (binding.mainPager.adapter as TabPageAdapter).getPluginAt(binding.mainPager.currentItem)
|
||||
this.menu?.findItem(R.id.nav_plugin_preferences)?.title = resourceHelper.gs(R.string.nav_preferences_plugin, plugin.name)
|
||||
this.menu?.findItem(R.id.nav_plugin_preferences)?.title = rh.gs(R.string.nav_preferences_plugin, plugin.name)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMenuOpened(featureId: Int, menu: Menu): Boolean {
|
||||
menuOpen = true
|
||||
if (binding.mainDrawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
binding.mainDrawerLayout.closeDrawers()
|
||||
}
|
||||
val result = super.onMenuOpened(featureId, menu)
|
||||
menu.findItem(R.id.nav_treatments)?.isEnabled = profileFunction.getProfile() != null
|
||||
return result
|
||||
}
|
||||
|
||||
override fun onPanelClosed(featureId: Int, menu: Menu) {
|
||||
menuOpen = false;
|
||||
super.onPanelClosed(featureId, menu)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
this.menu = menu
|
||||
menuInflater.inflate(R.menu.menu_main, menu)
|
||||
|
@ -281,6 +299,11 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
return true
|
||||
}
|
||||
|
||||
R.id.nav_treatments -> {
|
||||
startActivity(Intent(this, TreatmentsActivity::class.java))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.nav_setupwizard -> {
|
||||
protectionCheck.queryProtection(this, ProtectionCheck.Protection.PREFERENCES, {
|
||||
startActivity(Intent(this, SetupWizardActivity::class.java))
|
||||
|
@ -291,18 +314,18 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
R.id.nav_about -> {
|
||||
var message = "Build: ${BuildConfig.BUILDVERSION}\n"
|
||||
message += "Flavor: ${BuildConfig.FLAVOR}${BuildConfig.BUILD_TYPE}\n"
|
||||
message += "${resourceHelper.gs(R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.nightscoutVersionName}"
|
||||
if (buildHelper.isEngineeringMode()) message += "\n${resourceHelper.gs(R.string.engineering_mode_enabled)}"
|
||||
if (!fabricPrivacy.fabricEnabled()) message += "\n${resourceHelper.gs(R.string.fabric_upload_disabled)}"
|
||||
message += resourceHelper.gs(R.string.about_link_urls)
|
||||
message += "${rh.gs(R.string.configbuilder_nightscoutversion_label)} ${nsSettingsStatus.getVersion()}"
|
||||
if (buildHelper.isEngineeringMode()) message += "\n${rh.gs(R.string.engineering_mode_enabled)}"
|
||||
if (!fabricPrivacy.fabricEnabled()) message += "\n${rh.gs(R.string.fabric_upload_disabled)}"
|
||||
message += rh.gs(R.string.about_link_urls)
|
||||
val messageSpanned = SpannableString(message)
|
||||
Linkify.addLinks(messageSpanned, Linkify.WEB_URLS)
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(resourceHelper.gs(R.string.app_name) + " " + BuildConfig.VERSION)
|
||||
.setTitle(rh.gs(R.string.app_name) + " " + BuildConfig.VERSION)
|
||||
.setIcon(iconsProvider.getIcon())
|
||||
.setMessage(messageSpanned)
|
||||
.setPositiveButton(resourceHelper.gs(R.string.ok), null)
|
||||
.setNeutralButton(resourceHelper.gs(R.string.cta_dont_kill_my_app_info)) { _, _ -> DokiActivity.start(context = this@MainActivity) }
|
||||
.setPositiveButton(rh.gs(R.string.ok), null)
|
||||
.setNeutralButton(rh.gs(R.string.cta_dont_kill_my_app_info)) { _, _ -> DokiActivity.start(context = this@MainActivity) }
|
||||
.create().apply {
|
||||
show()
|
||||
findViewById<TextView>(android.R.id.message)?.movementMethod = LinkMovementMethod.getInstance()
|
||||
|
@ -312,6 +335,7 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
R.id.nav_exit -> {
|
||||
aapsLogger.debug(LTag.CORE, "Exiting")
|
||||
uel.log(Action.EXIT_AAPS, Sources.Aaps)
|
||||
rxBus.send(EventAppExit())
|
||||
finish()
|
||||
System.runFinalization()
|
||||
|
@ -346,6 +370,22 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
return actionBarDrawerToggle.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (binding.mainDrawerLayout.isDrawerOpen(GravityCompat.START)) {
|
||||
binding.mainDrawerLayout.closeDrawers()
|
||||
return
|
||||
}
|
||||
if (menuOpen) {
|
||||
this.menu?.close()
|
||||
return
|
||||
}
|
||||
if (binding.mainPager.currentItem != 0) {
|
||||
binding.mainPager.currentItem = 0
|
||||
return
|
||||
}
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
// Correct place for calling setUserStats() would be probably MainApp
|
||||
// but we need to have it called at least once a day. Thus this location
|
||||
|
||||
|
@ -353,7 +393,7 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
if (!fabricPrivacy.fabricEnabled()) return
|
||||
val closedLoopEnabled = if (constraintChecker.isClosedLoopAllowed().value()) "CLOSED_LOOP_ENABLED" else "CLOSED_LOOP_DISABLED"
|
||||
// Size is limited to 36 chars
|
||||
val remote = BuildConfig.REMOTE.toLowerCase(Locale.getDefault())
|
||||
val remote = BuildConfig.REMOTE.lowercase(Locale.getDefault())
|
||||
.replace("https://", "")
|
||||
.replace("http://", "")
|
||||
.replace(".git", "")
|
||||
|
@ -371,7 +411,7 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
if (!config.NSCLIENT && !config.PUMPCONTROL)
|
||||
activePlugin.activeAPS.let { fabricPrivacy.firebaseAnalytics.setUserProperty("Aps", it::class.java.simpleName) }
|
||||
activePlugin.activeBgSource.let { fabricPrivacy.firebaseAnalytics.setUserProperty("BgSource", it::class.java.simpleName) }
|
||||
fabricPrivacy.firebaseAnalytics.setUserProperty("Profile", activePlugin.activeProfileInterface.javaClass.simpleName)
|
||||
fabricPrivacy.firebaseAnalytics.setUserProperty("Profile", activePlugin.activeProfileSource.javaClass.simpleName)
|
||||
activePlugin.activeSensitivity.let { fabricPrivacy.firebaseAnalytics.setUserProperty("Sensitivity", it::class.java.simpleName) }
|
||||
activePlugin.activeInsulin.let { fabricPrivacy.firebaseAnalytics.setUserProperty("Insulin", it::class.java.simpleName) }
|
||||
// Add to crash log too
|
||||
|
@ -380,6 +420,7 @@ class MainActivity : NoSplashAppCompatActivity() {
|
|||
FirebaseCrashlytics.getInstance().setCustomKey("Remote", remote)
|
||||
FirebaseCrashlytics.getInstance().setCustomKey("Committed", BuildConfig.COMMITTED)
|
||||
FirebaseCrashlytics.getInstance().setCustomKey("Hash", hashes[0])
|
||||
FirebaseCrashlytics.getInstance().setCustomKey("Email", sp.getString(R.string.key_email_for_crash_report, ""))
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiManager;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import net.danlew.android.joda.JodaTimeAndroid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.AndroidInjector;
|
||||
import dagger.android.DaggerApplication;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
import info.nightscout.androidaps.db.StaticInjector;
|
||||
import info.nightscout.androidaps.dependencyInjection.DaggerAppComponent;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore;
|
||||
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils;
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||
import info.nightscout.androidaps.receivers.BTReceiver;
|
||||
import info.nightscout.androidaps.receivers.ChargingStateReceiver;
|
||||
import info.nightscout.androidaps.receivers.DataReceiver;
|
||||
import info.nightscout.androidaps.receivers.KeepAliveReceiver;
|
||||
import info.nightscout.androidaps.receivers.NetworkChangeReceiver;
|
||||
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
|
||||
import info.nightscout.androidaps.services.Intents;
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor;
|
||||
import info.nightscout.androidaps.utils.locale.LocaleHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
public class MainApp extends DaggerApplication {
|
||||
|
||||
static MainApp sInstance;
|
||||
private static Resources sResources;
|
||||
|
||||
static DatabaseHelper sDatabaseHelper = null;
|
||||
|
||||
@Inject PluginStore pluginStore;
|
||||
@Inject AAPSLogger aapsLogger;
|
||||
@Inject ActivityMonitor activityMonitor;
|
||||
@Inject VersionCheckerUtils versionCheckersUtils;
|
||||
@Inject SP sp;
|
||||
@Inject NSUpload nsUpload;
|
||||
@Inject Config config;
|
||||
|
||||
@Inject ConfigBuilderPlugin configBuilderPlugin;
|
||||
@Inject KeepAliveReceiver.KeepAliveManager keepAliveManager;
|
||||
@Inject List<PluginBase> plugins;
|
||||
|
||||
@Inject StaticInjector staticInjector; // TODO avoid , here fake only to initialize
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
aapsLogger.debug("onCreate");
|
||||
sInstance = this;
|
||||
sResources = getResources();
|
||||
LocaleHelper.INSTANCE.update(this);
|
||||
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||
/*
|
||||
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> {
|
||||
if (ex instanceof InternalError) {
|
||||
// usually the app trying to spawn a thread while being killed
|
||||
return;
|
||||
}
|
||||
aapsLogger.error("Uncaught exception crashing app", ex);
|
||||
});
|
||||
*/
|
||||
registerActivityLifecycleCallbacks(activityMonitor);
|
||||
|
||||
JodaTimeAndroid.init(this);
|
||||
|
||||
aapsLogger.debug("Version: " + BuildConfig.VERSION_NAME);
|
||||
aapsLogger.debug("BuildVersion: " + BuildConfig.BUILDVERSION);
|
||||
aapsLogger.debug("Remote: " + BuildConfig.REMOTE);
|
||||
|
||||
registerLocalBroadcastReceiver();
|
||||
|
||||
//trigger here to see the new version on app start after an update
|
||||
versionCheckersUtils.triggerCheckVersion();
|
||||
|
||||
// Register all tabs in app here
|
||||
pluginStore.setPlugins(plugins);
|
||||
configBuilderPlugin.initialize();
|
||||
|
||||
nsUpload.uploadAppStart();
|
||||
|
||||
new Thread(() -> keepAliveManager.setAlarm(this)).start();
|
||||
doMigrations();
|
||||
}
|
||||
|
||||
|
||||
private void doMigrations() {
|
||||
// set values for different builds
|
||||
if (!sp.contains(R.string.key_ns_alarms))
|
||||
sp.putBoolean(R.string.key_ns_alarms, config.getNSCLIENT());
|
||||
if (!sp.contains(R.string.key_ns_announcements))
|
||||
sp.putBoolean(R.string.key_ns_announcements, config.getNSCLIENT());
|
||||
if (!sp.contains(R.string.key_language))
|
||||
sp.putString(R.string.key_language, "default");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
|
||||
return DaggerAppComponent
|
||||
.builder()
|
||||
.application(this)
|
||||
.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void registerLocalBroadcastReceiver() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intents.ACTION_NEW_TREATMENT);
|
||||
filter.addAction(Intents.ACTION_CHANGED_TREATMENT);
|
||||
filter.addAction(Intents.ACTION_REMOVED_TREATMENT);
|
||||
filter.addAction(Intents.ACTION_NEW_SGV);
|
||||
filter.addAction(Intents.ACTION_NEW_PROFILE);
|
||||
filter.addAction(Intents.ACTION_NEW_MBG);
|
||||
filter.addAction(Intents.ACTION_NEW_CAL);
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(new DataReceiver(), filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_TIME_CHANGED);
|
||||
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
registerReceiver(new TimeDateOrTZChangeReceiver(), filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
|
||||
registerReceiver(new NetworkChangeReceiver(), filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_POWER_CONNECTED);
|
||||
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
|
||||
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
registerReceiver(new ChargingStateReceiver(), filter);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
|
||||
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
|
||||
registerReceiver(new BTReceiver(), filter);
|
||||
}
|
||||
|
||||
public static DatabaseHelper getDbHelper() {
|
||||
return sDatabaseHelper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTerminate() {
|
||||
aapsLogger.debug(LTag.CORE, "onTerminate");
|
||||
unregisterActivityLifecycleCallbacks(activityMonitor);
|
||||
keepAliveManager.cancelAlarm(this);
|
||||
super.onTerminate();
|
||||
}
|
||||
}
|
193
app/src/main/java/info/nightscout/androidaps/MainApp.kt
Normal file
193
app/src/main/java/info/nightscout/androidaps/MainApp.kt
Normal file
|
@ -0,0 +1,193 @@
|
|||
package info.nightscout.androidaps
|
||||
|
||||
import android.bluetooth.BluetoothDevice
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Build
|
||||
import com.uber.rxdogtag.RxDogTag
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.DaggerApplication
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.database.entities.UserEntry
|
||||
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction
|
||||
import info.nightscout.androidaps.database.transactions.VersionChangeTransaction
|
||||
import info.nightscout.androidaps.db.CompatDBHelper
|
||||
import info.nightscout.androidaps.di.DaggerAppComponent
|
||||
import info.nightscout.androidaps.di.StaticInjector
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.ConfigBuilder
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
|
||||
import info.nightscout.androidaps.receivers.BTReceiver
|
||||
import info.nightscout.androidaps.receivers.ChargingStateReceiver
|
||||
import info.nightscout.androidaps.receivers.KeepAliveReceiver.KeepAliveManager
|
||||
import info.nightscout.androidaps.receivers.NetworkChangeReceiver
|
||||
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver
|
||||
import info.nightscout.androidaps.services.AlarmSoundServiceHelper
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.locale.LocaleHelper
|
||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.exceptions.UndeliverableException
|
||||
import io.reactivex.plugins.RxJavaPlugins
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import net.danlew.android.joda.JodaTimeAndroid
|
||||
import java.io.IOException
|
||||
import java.net.SocketException
|
||||
import javax.inject.Inject
|
||||
|
||||
class MainApp : DaggerApplication() {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
@Inject lateinit var pluginStore: PluginStore
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var activityMonitor: ActivityMonitor
|
||||
@Inject lateinit var versionCheckersUtils: VersionCheckerUtils
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var configBuilder: ConfigBuilder
|
||||
@Inject lateinit var keepAliveManager: KeepAliveManager
|
||||
@Inject lateinit var plugins: List<@JvmSuppressWildcards PluginBase>
|
||||
@Inject lateinit var compatDBHelper: CompatDBHelper
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var staticInjector: StaticInjector// TODO avoid , here fake only to initialize
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var passwordCheck: PasswordCheck
|
||||
@Inject lateinit var alarmSoundServiceHelper: AlarmSoundServiceHelper
|
||||
@Inject lateinit var notificationStore: NotificationStore
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
aapsLogger.debug("onCreate")
|
||||
RxDogTag.install()
|
||||
setRxErrorHandler()
|
||||
LocaleHelper.update(this)
|
||||
|
||||
var gitRemote: String? = BuildConfig.REMOTE
|
||||
var commitHash: String? = BuildConfig.HEAD
|
||||
if (gitRemote?.contains("NoGitSystemAvailable") == true) {
|
||||
gitRemote = null
|
||||
commitHash = null
|
||||
}
|
||||
disposable += repository.runTransaction(VersionChangeTransaction(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, gitRemote, commitHash)).subscribe()
|
||||
if (sp.getBoolean(R.string.key_ns_logappstartedevent, config.APS))
|
||||
disposable += repository
|
||||
.runTransaction(
|
||||
InsertIfNewByTimestampTherapyEventTransaction(
|
||||
timestamp = dateUtil.now(),
|
||||
type = TherapyEvent.Type.NOTE,
|
||||
note = getString(info.nightscout.androidaps.core.R.string.androidaps_start) + " - " + Build.MANUFACTURER + " " + Build.MODEL,
|
||||
glucoseUnit = TherapyEvent.GlucoseUnit.MGDL
|
||||
)
|
||||
)
|
||||
.subscribe()
|
||||
disposable += compatDBHelper.dbChangeDisposable()
|
||||
registerActivityLifecycleCallbacks(activityMonitor)
|
||||
JodaTimeAndroid.init(this)
|
||||
aapsLogger.debug("Version: " + BuildConfig.VERSION_NAME)
|
||||
aapsLogger.debug("BuildVersion: " + BuildConfig.BUILDVERSION)
|
||||
aapsLogger.debug("Remote: " + BuildConfig.REMOTE)
|
||||
registerLocalBroadcastReceiver()
|
||||
|
||||
// trigger here to see the new version on app start after an update
|
||||
versionCheckersUtils.triggerCheckVersion()
|
||||
// check if identification is set
|
||||
if (buildHelper.isDev() && sp.getStringOrNull(R.string.key_email_for_crash_report, null).isNullOrBlank())
|
||||
notificationStore.add(Notification(Notification.IDENTIFICATION_NOT_SET, getString(R.string.identification_not_set), Notification.INFO))
|
||||
|
||||
// Register all tabs in app here
|
||||
pluginStore.plugins = plugins
|
||||
configBuilder.initialize()
|
||||
keepAliveManager.setAlarm(this)
|
||||
doMigrations()
|
||||
uel.log(UserEntry.Action.START_AAPS, UserEntry.Sources.Aaps)
|
||||
passwordCheck.passwordResetCheck(this)
|
||||
}
|
||||
|
||||
private fun setRxErrorHandler() {
|
||||
RxJavaPlugins.setErrorHandler { t: Throwable ->
|
||||
var e = t
|
||||
if (e is UndeliverableException) {
|
||||
e = e.cause!!
|
||||
}
|
||||
if (e is IOException || e is SocketException) {
|
||||
// fine, irrelevant network problem or API that throws on cancellation
|
||||
return@setErrorHandler
|
||||
}
|
||||
if (e is InterruptedException) {
|
||||
// fine, some blocking code was interrupted by a dispose call
|
||||
return@setErrorHandler
|
||||
}
|
||||
if (e is NullPointerException || e is IllegalArgumentException) {
|
||||
// that's likely a bug in the application
|
||||
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), e)
|
||||
return@setErrorHandler
|
||||
}
|
||||
if (e is IllegalStateException) {
|
||||
// that's a bug in RxJava or in a custom operator
|
||||
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), e)
|
||||
return@setErrorHandler
|
||||
}
|
||||
aapsLogger.warn(LTag.CORE, "Undeliverable exception received, not sure what to do", e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doMigrations() {
|
||||
// set values for different builds
|
||||
if (!sp.contains(R.string.key_ns_alarms)) sp.putBoolean(R.string.key_ns_alarms, config.NSCLIENT)
|
||||
if (!sp.contains(R.string.key_ns_announcements)) sp.putBoolean(R.string.key_ns_announcements, config.NSCLIENT)
|
||||
if (!sp.contains(R.string.key_language)) sp.putString(R.string.key_language, "default")
|
||||
}
|
||||
|
||||
override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
|
||||
return DaggerAppComponent
|
||||
.builder()
|
||||
.application(this)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun registerLocalBroadcastReceiver() {
|
||||
var filter = IntentFilter()
|
||||
filter.addAction(Intent.ACTION_TIME_CHANGED)
|
||||
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED)
|
||||
registerReceiver(TimeDateOrTZChangeReceiver(), filter)
|
||||
filter = IntentFilter()
|
||||
@Suppress("DEPRECATION")
|
||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
|
||||
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION)
|
||||
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
||||
registerReceiver(NetworkChangeReceiver(), filter)
|
||||
filter = IntentFilter()
|
||||
filter.addAction(Intent.ACTION_POWER_CONNECTED)
|
||||
filter.addAction(Intent.ACTION_POWER_DISCONNECTED)
|
||||
filter.addAction(Intent.ACTION_BATTERY_CHANGED)
|
||||
registerReceiver(ChargingStateReceiver(), filter)
|
||||
filter = IntentFilter()
|
||||
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
|
||||
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
|
||||
registerReceiver(BTReceiver(), filter)
|
||||
}
|
||||
|
||||
override fun onTerminate() {
|
||||
aapsLogger.debug(LTag.CORE, "onTerminate")
|
||||
unregisterActivityLifecycleCallbacks(activityMonitor)
|
||||
keepAliveManager.cancelAlarm(this)
|
||||
alarmSoundServiceHelper.stopService(this)
|
||||
super.onTerminate()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,439 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.DatePickerDialog
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import com.jjoe64.graphview.GraphView
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.databinding.ActivityHistorybrowseBinding
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.Loop
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewData
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventBucketedDataCreated
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.Translator
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.min
|
||||
|
||||
class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var sensitivityOref1Plugin: SensitivityOref1Plugin
|
||||
@Inject lateinit var sensitivityAAPSPlugin: SensitivityAAPSPlugin
|
||||
@Inject lateinit var sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var overviewMenus: OverviewMenus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var loop: Loop
|
||||
@Inject lateinit var nsDeviceStatus: NSDeviceStatus
|
||||
@Inject lateinit var translator: Translator
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val secondaryGraphs = ArrayList<GraphView>()
|
||||
private val secondaryGraphsLabel = ArrayList<TextView>()
|
||||
|
||||
private var axisWidth: Int = 0
|
||||
private var rangeToDisplay = 24 // for graph
|
||||
// private var start: Long = 0
|
||||
|
||||
private lateinit var iobCobCalculator: IobCobCalculatorPlugin
|
||||
private lateinit var overviewData: OverviewData
|
||||
|
||||
private lateinit var binding: ActivityHistorybrowseBinding
|
||||
private var destroyed = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityHistorybrowseBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
// We don't want to use injected singletons but own instance working on top of different data
|
||||
iobCobCalculator =
|
||||
IobCobCalculatorPlugin(
|
||||
injector,
|
||||
aapsLogger,
|
||||
aapsSchedulers,
|
||||
rxBus,
|
||||
sp,
|
||||
rh,
|
||||
profileFunction,
|
||||
activePlugin,
|
||||
sensitivityOref1Plugin,
|
||||
sensitivityAAPSPlugin,
|
||||
sensitivityWeightedAveragePlugin,
|
||||
fabricPrivacy,
|
||||
dateUtil,
|
||||
repository
|
||||
)
|
||||
overviewData =
|
||||
OverviewData(
|
||||
injector,
|
||||
aapsLogger,
|
||||
rh,
|
||||
dateUtil,
|
||||
sp,
|
||||
activePlugin,
|
||||
defaultValueHelper,
|
||||
profileFunction,
|
||||
config,
|
||||
loop,
|
||||
nsDeviceStatus,
|
||||
repository,
|
||||
overviewMenus,
|
||||
iobCobCalculator,
|
||||
translator
|
||||
)
|
||||
|
||||
binding.left.setOnClickListener {
|
||||
adjustTimeRange(overviewData.fromTime - T.hours(rangeToDisplay.toLong()).msecs())
|
||||
loadAll("onClickLeft")
|
||||
}
|
||||
binding.right.setOnClickListener {
|
||||
adjustTimeRange(overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs())
|
||||
loadAll("onClickRight")
|
||||
}
|
||||
binding.end.setOnClickListener {
|
||||
setTime(dateUtil.now())
|
||||
loadAll("onClickEnd")
|
||||
}
|
||||
binding.zoom.setOnClickListener {
|
||||
rangeToDisplay += 6
|
||||
rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay
|
||||
setTime(overviewData.fromTime)
|
||||
loadAll("rangeChange")
|
||||
}
|
||||
binding.zoom.setOnLongClickListener {
|
||||
Calendar.getInstance().also { calendar ->
|
||||
calendar.timeInMillis = overviewData.fromTime
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
setTime(calendar.timeInMillis)
|
||||
}
|
||||
loadAll("onLongClickZoom")
|
||||
true
|
||||
}
|
||||
|
||||
// create an OnDateSetListener
|
||||
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
Calendar.getInstance().also { calendar ->
|
||||
calendar.timeInMillis = overviewData.fromTime
|
||||
calendar[Calendar.YEAR] = year
|
||||
calendar[Calendar.MONTH] = monthOfYear
|
||||
calendar[Calendar.DAY_OF_MONTH] = dayOfMonth
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
setTime(calendar.timeInMillis)
|
||||
binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
|
||||
}
|
||||
loadAll("onClickDate")
|
||||
}
|
||||
|
||||
binding.date.setOnClickListener {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = overviewData.fromTime
|
||||
DatePickerDialog(
|
||||
this, dateSetListener,
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
|
||||
val dm = DisplayMetrics()
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
|
||||
display?.getRealMetrics(dm)
|
||||
else
|
||||
@Suppress("DEPRECATION") windowManager.defaultDisplay.getMetrics(dm)
|
||||
|
||||
|
||||
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
|
||||
binding.bgGraph.gridLabelRenderer?.gridColor = rh.gc(R.color.graphgrid)
|
||||
binding.bgGraph.gridLabelRenderer?.reloadStyles()
|
||||
binding.bgGraph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
|
||||
overviewMenus.setupChartMenu(binding.chartMenuButton)
|
||||
prepareGraphsIfNeeded(overviewMenus.setting.size)
|
||||
savedInstanceState?.let { bundle ->
|
||||
rangeToDisplay = bundle.getInt("rangeToDisplay", 0)
|
||||
overviewData.fromTime = bundle.getLong("start", 0)
|
||||
overviewData.toTime = bundle.getLong("end", 0)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
iobCobCalculator.stopCalculation("onPause")
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroy() {
|
||||
destroyed = true
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
// catch only events from iobCobCalculator
|
||||
if (it.cause is EventCustomCalculationFinished)
|
||||
refreshLoop("EventAutosensCalculationFinished")
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventIobCalculationProgress::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
if (it.cause is EventCustomCalculationFinished)
|
||||
binding.overviewIobcalculationprogess.text = it.progress
|
||||
}, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventRefreshOverview::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ updateGUI("EventRefreshOverview") }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventBucketedDataCreated::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({
|
||||
overviewData.prepareBucketedData("EventBucketedDataCreated")
|
||||
overviewData.prepareBgData("EventBucketedDataCreated")
|
||||
rxBus.send(EventRefreshOverview("EventBucketedDataCreated"))
|
||||
}, fabricPrivacy::logException)
|
||||
|
||||
if (overviewData.fromTime == 0L) {
|
||||
// set start of current day
|
||||
setTime(dateUtil.now())
|
||||
loadAll("onResume")
|
||||
} else {
|
||||
updateGUI("onResume")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putInt("rangeToDisplay", rangeToDisplay)
|
||||
outState.putLong("start", overviewData.fromTime)
|
||||
outState.putLong("end", overviewData.toTime)
|
||||
}
|
||||
|
||||
private fun prepareGraphsIfNeeded(numOfGraphs: Int) {
|
||||
if (numOfGraphs != secondaryGraphs.size - 1) {
|
||||
//aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
|
||||
// rebuild needed
|
||||
secondaryGraphs.clear()
|
||||
secondaryGraphsLabel.clear()
|
||||
binding.iobGraph.removeAllViews()
|
||||
for (i in 1 until numOfGraphs) {
|
||||
val relativeLayout = RelativeLayout(this)
|
||||
relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
||||
val graph = GraphView(this)
|
||||
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, rh.dpToPx(100)).also { it.setMargins(0, rh.dpToPx(15), 0, rh.dpToPx(10)) }
|
||||
graph.gridLabelRenderer?.gridColor = rh.gc(R.color.graphgrid)
|
||||
graph.gridLabelRenderer?.reloadStyles()
|
||||
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
|
||||
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
graph.gridLabelRenderer?.numVerticalLabels = 3
|
||||
graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
|
||||
relativeLayout.addView(graph)
|
||||
|
||||
val label = TextView(this)
|
||||
val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(rh.dpToPx(30), rh.dpToPx(25), 0, 0) }
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP)
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
|
||||
label.layoutParams = layoutParams
|
||||
relativeLayout.addView(label)
|
||||
secondaryGraphsLabel.add(label)
|
||||
|
||||
binding.iobGraph.addView(relativeLayout)
|
||||
secondaryGraphs.add(graph)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("SameParameterValue")
|
||||
private fun loadAll(from: String) {
|
||||
updateDate()
|
||||
Thread {
|
||||
overviewData.prepareBgData("$from")
|
||||
overviewData.prepareTreatmentsData(from)
|
||||
rxBus.send(EventRefreshOverview("loadAll_$from"))
|
||||
overviewData.prepareTemporaryTargetData(from)
|
||||
rxBus.send(EventRefreshOverview("loadAll_$from"))
|
||||
overviewData.prepareBasalData(from)
|
||||
rxBus.send(EventRefreshOverview(from))
|
||||
aapsLogger.debug(LTag.UI, "loadAll $from finished")
|
||||
runCalculation(from)
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun setTime(start: Long) {
|
||||
GregorianCalendar().also { calendar ->
|
||||
calendar.timeInMillis = start
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] -= (calendar[Calendar.HOUR_OF_DAY] % rangeToDisplay)
|
||||
adjustTimeRange(calendar.timeInMillis)
|
||||
}
|
||||
}
|
||||
|
||||
private fun adjustTimeRange(start: Long) {
|
||||
overviewData.fromTime = start
|
||||
overviewData.toTime = overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs()
|
||||
overviewData.endTime = overviewData.toTime
|
||||
}
|
||||
|
||||
private fun runCalculation(from: String) {
|
||||
Thread {
|
||||
iobCobCalculator.stopCalculation(from)
|
||||
iobCobCalculator.stopCalculationTrigger = false
|
||||
iobCobCalculator.runCalculation(from, overviewData.toTime, bgDataReload = true, limitDataToOldestAvailable = false, cause = EventCustomCalculationFinished())
|
||||
}.start()
|
||||
}
|
||||
|
||||
@Volatile
|
||||
var runningRefresh = false
|
||||
private fun refreshLoop(from: String) {
|
||||
if (runningRefresh) return
|
||||
runningRefresh = true
|
||||
overviewData.prepareIobAutosensData(from)
|
||||
rxBus.send(EventRefreshOverview(from))
|
||||
aapsLogger.debug(LTag.UI, "refreshLoop finished")
|
||||
runningRefresh = false
|
||||
}
|
||||
|
||||
fun updateDate() {
|
||||
binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime)
|
||||
binding.zoom.text = rangeToDisplay.toString()
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@SuppressLint("SetTextI18n")
|
||||
fun updateGUI(from: String) {
|
||||
aapsLogger.debug(LTag.UI, "updateGui $from")
|
||||
|
||||
updateDate()
|
||||
|
||||
val pump = activePlugin.activePump
|
||||
val graphData = GraphData(injector, binding.bgGraph, overviewData)
|
||||
val menuChartSettings = overviewMenus.setting
|
||||
graphData.addInRangeArea(overviewData.fromTime, overviewData.endTime, defaultValueHelper.determineLowLine(), defaultValueHelper.determineHighLine())
|
||||
graphData.addBgReadings(menuChartSettings[0][OverviewMenus.CharType.PRE.ordinal])
|
||||
if (buildHelper.isDev()) graphData.addBucketedData()
|
||||
graphData.addTreatments()
|
||||
if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal])
|
||||
graphData.addActivity(0.8)
|
||||
if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal])
|
||||
graphData.addBasals()
|
||||
graphData.addTargetLine()
|
||||
graphData.addNowLine(dateUtil.now())
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
graphData.setNumVerticalLabels()
|
||||
graphData.formatAxis(overviewData.fromTime, overviewData.endTime)
|
||||
|
||||
graphData.performUpdate()
|
||||
|
||||
// 2nd graphs
|
||||
prepareGraphsIfNeeded(menuChartSettings.size)
|
||||
val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
|
||||
|
||||
val now = System.currentTimeMillis()
|
||||
for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
|
||||
val secondGraphData = GraphData(injector, secondaryGraphs[g], overviewData)
|
||||
var useABSForScale = false
|
||||
var useIobForScale = false
|
||||
var useCobForScale = false
|
||||
var useDevForScale = false
|
||||
var useRatioForScale = false
|
||||
var useDSForScale = false
|
||||
var useBGIForScale = false
|
||||
when {
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] -> useBGIForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
|
||||
}
|
||||
val alignDevBgiScale = menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] && menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]
|
||||
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(useABSForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(useIobForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(useCobForScale, if (useCobForScale) 1.0 else 0.5)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(useDevForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal]) secondGraphData.addMinusBGI(useBGIForScale, if (alignDevBgiScale) 1.0 else 0.8)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(useRatioForScale, if (useRatioForScale) 1.0 else 0.8)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(useDSForScale, 1.0)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(overviewData.fromTime, overviewData.endTime)
|
||||
secondGraphData.addNowLine(now)
|
||||
secondaryGraphsData.add(secondGraphData)
|
||||
}
|
||||
for (g in 0 until min(secondaryGraphs.size, menuChartSettings.size + 1)) {
|
||||
secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1)
|
||||
secondaryGraphs[g].visibility = (
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.BGI.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
|
||||
).toVisibility()
|
||||
secondaryGraphsData[g].performUpdate()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,28 +8,29 @@ import android.os.Bundle
|
|||
import androidx.annotation.XmlRes
|
||||
import androidx.preference.*
|
||||
import dagger.android.support.AndroidSupportInjection
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
||||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||
import info.nightscout.androidaps.danars.DanaRSPlugin
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.events.EventRebuildTabs
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin
|
||||
|
@ -47,12 +48,13 @@ import info.nightscout.androidaps.plugins.source.EversensePlugin
|
|||
import info.nightscout.androidaps.plugins.source.GlimpPlugin
|
||||
import info.nightscout.androidaps.plugins.source.PoctechPlugin
|
||||
import info.nightscout.androidaps.plugins.source.TomatoPlugin
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.androidaps.plugins.source.GlunovoPlugin
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog.show
|
||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
|
||||
class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChangeListener {
|
||||
|
@ -60,8 +62,8 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
private var pluginId = -1
|
||||
private var filter = ""
|
||||
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var pluginStore: PluginStore
|
||||
|
@ -89,6 +91,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
@Inject lateinit var glimpPlugin: GlimpPlugin
|
||||
@Inject lateinit var poctechPlugin: PoctechPlugin
|
||||
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
||||
@Inject lateinit var glunovoPlugin: GlunovoPlugin
|
||||
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
||||
@Inject lateinit var statusLinePlugin: StatusLinePlugin
|
||||
@Inject lateinit var tidepoolPlugin: TidepoolPlugin
|
||||
|
@ -99,6 +102,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
@Inject lateinit var passwordCheck: PasswordCheck
|
||||
@Inject lateinit var nsSettingStatus: NSSettingsStatus
|
||||
@Inject lateinit var openHumansUploader: OpenHumansUploader
|
||||
@Inject lateinit var diaconnG8Plugin: DiaconnG8Plugin
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
AndroidSupportInjection.inject(this)
|
||||
|
@ -158,6 +162,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
addPreferencesFromResourceIfEnabled(eversensePlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(dexcomPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(tomatoPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(glunovoPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(poctechPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(glimpPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(loopPlugin, rootKey, config.APS)
|
||||
|
@ -173,6 +178,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
addPreferencesFromResourceIfEnabled(localInsightPlugin, rootKey, config.PUMPDRIVERS)
|
||||
addPreferencesFromResourceIfEnabled(comboPlugin, rootKey, config.PUMPDRIVERS)
|
||||
addPreferencesFromResourceIfEnabled(medtronicPumpPlugin, rootKey, config.PUMPDRIVERS)
|
||||
addPreferencesFromResourceIfEnabled(diaconnG8Plugin, rootKey, config.PUMPDRIVERS)
|
||||
addPreferencesFromResource(R.xml.pref_pump, rootKey, config.PUMPDRIVERS)
|
||||
addPreferencesFromResourceIfEnabled(virtualPumpPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(insulinOrefFreePeakPlugin, rootKey)
|
||||
|
@ -182,7 +188,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
addPreferencesFromResourceIfEnabled(automationPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(wearPlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(statusLinePlugin, rootKey)
|
||||
addPreferencesFromResource(R.xml.pref_alerts, rootKey) // TODO not organized well
|
||||
addPreferencesFromResource(R.xml.pref_alerts, rootKey)
|
||||
addPreferencesFromResource(R.xml.pref_datachoices, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(maintenancePlugin, rootKey)
|
||||
addPreferencesFromResourceIfEnabled(openHumansUploader, rootKey)
|
||||
|
@ -194,21 +200,21 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
rxBus.send(EventPreferenceChange(key))
|
||||
if (key == resourceHelper.gs(R.string.key_language)) {
|
||||
if (key == rh.gs(R.string.key_language)) {
|
||||
rxBus.send(EventRebuildTabs(true))
|
||||
//recreate() does not update language so better close settings
|
||||
activity?.finish()
|
||||
}
|
||||
if (key == resourceHelper.gs(R.string.key_short_tabtitles)) {
|
||||
if (key == rh.gs(R.string.key_short_tabtitles)) {
|
||||
rxBus.send(EventRebuildTabs())
|
||||
}
|
||||
if (key == resourceHelper.gs(R.string.key_units)) {
|
||||
if (key == rh.gs(R.string.key_units)) {
|
||||
activity?.recreate()
|
||||
return
|
||||
}
|
||||
if (key == resourceHelper.gs(R.string.key_openapsama_useautosens) && sp.getBoolean(R.string.key_openapsama_useautosens, false)) {
|
||||
if (key == rh.gs(R.string.key_openapsama_useautosens) && sp.getBoolean(R.string.key_openapsama_useautosens, false)) {
|
||||
activity?.let {
|
||||
show(it, resourceHelper.gs(R.string.configbuilder_sensitivity), resourceHelper.gs(R.string.sensitivity_warning))
|
||||
show(it, rh.gs(R.string.configbuilder_sensitivity), rh.gs(R.string.sensitivity_warning))
|
||||
}
|
||||
}
|
||||
checkForBiometricFallback(key)
|
||||
|
@ -225,15 +231,15 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
|
||||
private fun checkForBiometricFallback(key: String) {
|
||||
// Biometric protection activated without set master password
|
||||
if ((resourceHelper.gs(R.string.key_settings_protection) == key ||
|
||||
resourceHelper.gs(R.string.key_application_protection) == key ||
|
||||
resourceHelper.gs(R.string.key_bolus_protection) == key) &&
|
||||
if ((rh.gs(R.string.key_settings_protection) == key ||
|
||||
rh.gs(R.string.key_application_protection) == key ||
|
||||
rh.gs(R.string.key_bolus_protection) == key) &&
|
||||
sp.getString(R.string.key_master_password, "") == "" &&
|
||||
sp.getInt(key, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal
|
||||
) {
|
||||
activity?.let {
|
||||
val title = resourceHelper.gs(R.string.unsecure_fallback_biometric)
|
||||
val message = resourceHelper.gs(R.string.master_password_missing, resourceHelper.gs(R.string.configbuilder_general), resourceHelper.gs(R.string.protection))
|
||||
val title = rh.gs(R.string.unsecure_fallback_biometric)
|
||||
val message = rh.gs(R.string.master_password_missing, rh.gs(R.string.configbuilder_general), rh.gs(R.string.protection))
|
||||
show(it, title = title, message = message)
|
||||
}
|
||||
}
|
||||
|
@ -242,10 +248,10 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
val isBiometricActivated = sp.getInt(R.string.key_settings_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal ||
|
||||
sp.getInt(R.string.key_application_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal ||
|
||||
sp.getInt(R.string.key_bolus_protection, ProtectionCheck.ProtectionType.NONE.ordinal) == ProtectionCheck.ProtectionType.BIOMETRIC.ordinal
|
||||
if (resourceHelper.gs(R.string.key_master_password) == key && sp.getString(key, "") == "" && isBiometricActivated) {
|
||||
if (rh.gs(R.string.key_master_password) == key && sp.getString(key, "") == "" && isBiometricActivated) {
|
||||
activity?.let {
|
||||
val title = resourceHelper.gs(R.string.unsecure_fallback_biometric)
|
||||
val message = resourceHelper.gs(R.string.unsecure_fallback_descriotion_biometric)
|
||||
val title = rh.gs(R.string.unsecure_fallback_biometric)
|
||||
val message = rh.gs(R.string.unsecure_fallback_descriotion_biometric)
|
||||
show(it, title = title, message = message)
|
||||
}
|
||||
}
|
||||
|
@ -275,11 +281,11 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
|
||||
private fun adjustUnitDependentPrefs(pref: Preference) { // convert preferences values to current units
|
||||
val unitDependent = arrayOf(
|
||||
resourceHelper.gs(R.string.key_hypo_target),
|
||||
resourceHelper.gs(R.string.key_activity_target),
|
||||
resourceHelper.gs(R.string.key_eatingsoon_target),
|
||||
resourceHelper.gs(R.string.key_high_mark),
|
||||
resourceHelper.gs(R.string.key_low_mark)
|
||||
rh.gs(R.string.key_hypo_target),
|
||||
rh.gs(R.string.key_activity_target),
|
||||
rh.gs(R.string.key_eatingsoon_target),
|
||||
rh.gs(R.string.key_high_mark),
|
||||
rh.gs(R.string.key_low_mark)
|
||||
)
|
||||
if (unitDependent.toList().contains(pref.key) && pref is EditTextPreference) {
|
||||
val converted = Profile.toCurrentUnits(profileFunction, SafeParse.stringToDouble(pref.text))
|
||||
|
@ -319,20 +325,20 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
pref.setSummary(pref.entry)
|
||||
// Preferences
|
||||
// Preferences
|
||||
if (pref.getKey() == resourceHelper.gs(R.string.key_settings_protection)) {
|
||||
val pass: Preference? = findPreference(resourceHelper.gs(R.string.key_settings_password))
|
||||
if (pref.getKey() == rh.gs(R.string.key_settings_protection)) {
|
||||
val pass: Preference? = findPreference(rh.gs(R.string.key_settings_password))
|
||||
if (pass != null) pass.isEnabled = pref.value == ProtectionCheck.ProtectionType.CUSTOM_PASSWORD.ordinal.toString()
|
||||
}
|
||||
// Application
|
||||
// Application
|
||||
if (pref.getKey() == resourceHelper.gs(R.string.key_application_protection)) {
|
||||
val pass: Preference? = findPreference(resourceHelper.gs(R.string.key_application_password))
|
||||
if (pref.getKey() == rh.gs(R.string.key_application_protection)) {
|
||||
val pass: Preference? = findPreference(rh.gs(R.string.key_application_password))
|
||||
if (pass != null) pass.isEnabled = pref.value == ProtectionCheck.ProtectionType.CUSTOM_PASSWORD.ordinal.toString()
|
||||
}
|
||||
// Bolus
|
||||
// Bolus
|
||||
if (pref.getKey() == resourceHelper.gs(R.string.key_bolus_protection)) {
|
||||
val pass: Preference? = findPreference(resourceHelper.gs(R.string.key_bolus_password))
|
||||
if (pref.getKey() == rh.gs(R.string.key_bolus_protection)) {
|
||||
val pass: Preference? = findPreference(rh.gs(R.string.key_bolus_password))
|
||||
if (pass != null) pass.isEnabled = pref.value == ProtectionCheck.ProtectionType.CUSTOM_PASSWORD.ordinal.toString()
|
||||
}
|
||||
}
|
||||
|
@ -350,10 +356,10 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
}
|
||||
|
||||
val hmacPasswords = arrayOf(
|
||||
resourceHelper.gs(R.string.key_bolus_password),
|
||||
resourceHelper.gs(R.string.key_master_password),
|
||||
resourceHelper.gs(R.string.key_application_password),
|
||||
resourceHelper.gs(R.string.key_settings_password)
|
||||
rh.gs(R.string.key_bolus_password),
|
||||
rh.gs(R.string.key_master_password),
|
||||
rh.gs(R.string.key_application_password),
|
||||
rh.gs(R.string.key_settings_password)
|
||||
)
|
||||
|
||||
if (pref is Preference) {
|
||||
|
@ -361,7 +367,7 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
if (sp.getString(pref.key, "").startsWith("hmac:")) {
|
||||
pref.summary = "******"
|
||||
} else {
|
||||
pref.summary = resourceHelper.gs(R.string.password_not_set)
|
||||
pref.summary = rh.gs(R.string.password_not_set)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,26 +396,26 @@ class MyPreferenceFragment : PreferenceFragmentCompat(), OnSharedPreferenceChang
|
|||
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
|
||||
context?.let { context ->
|
||||
if (preference != null) {
|
||||
if (preference.key == resourceHelper.gs(R.string.key_master_password)) {
|
||||
if (preference.key == rh.gs(R.string.key_master_password)) {
|
||||
passwordCheck.queryPassword(context, R.string.current_master_password, R.string.key_master_password, {
|
||||
passwordCheck.setPassword(context, R.string.master_password, R.string.key_master_password)
|
||||
})
|
||||
return true
|
||||
}
|
||||
if (preference.key == resourceHelper.gs(R.string.key_settings_password)) {
|
||||
if (preference.key == rh.gs(R.string.key_settings_password)) {
|
||||
passwordCheck.setPassword(context, R.string.settings_password, R.string.key_settings_password)
|
||||
return true
|
||||
}
|
||||
if (preference.key == resourceHelper.gs(R.string.key_bolus_password)) {
|
||||
if (preference.key == rh.gs(R.string.key_bolus_password)) {
|
||||
passwordCheck.setPassword(context, R.string.bolus_password, R.string.key_bolus_password)
|
||||
return true
|
||||
}
|
||||
if (preference.key == resourceHelper.gs(R.string.key_application_password)) {
|
||||
if (preference.key == rh.gs(R.string.key_application_password)) {
|
||||
passwordCheck.setPassword(context, R.string.application_password, R.string.key_application_password)
|
||||
return true
|
||||
}
|
||||
// NSClient copy settings
|
||||
if (preference.key == resourceHelper.gs(R.string.key_statuslights_copy_ns)) {
|
||||
if (preference.key == rh.gs(R.string.key_statuslights_copy_ns)) {
|
||||
nsSettingStatus.copyStatusLightsNsSettings(context)
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class PreferencesActivity : NoSplashAppCompatActivity(), PreferenceFragmentCompa
|
|||
override fun afterTextChanged(s: Editable) {}
|
||||
})
|
||||
|
||||
title = resourceHelper.gs(R.string.nav_preferences)
|
||||
title = rh.gs(R.string.nav_preferences)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||
myPreferenceFragment = MyPreferenceFragment()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
|
@ -7,40 +8,39 @@ import android.text.TextWatcher
|
|||
import android.view.Menu
|
||||
import android.widget.PopupMenu
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.data.defaultProfile.DefaultProfileDPV
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.data.PureProfile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
|
||||
import info.nightscout.androidaps.databinding.ActivityProfilehelperBinding
|
||||
import info.nightscout.androidaps.db.ProfileSwitch
|
||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.utils.defaultProfile.DefaultProfileDPV
|
||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||
import java.text.DecimalFormat
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var tddCalculator: TddCalculator
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var defaultProfile: DefaultProfile
|
||||
@Inject lateinit var defaultProfileDPV: DefaultProfileDPV
|
||||
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
enum class ProfileType {
|
||||
MOTOL_DEFAULT,
|
||||
|
@ -61,7 +61,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
private lateinit var profileList: ArrayList<CharSequence>
|
||||
private val profileUsed = arrayOf(0, 0)
|
||||
|
||||
private lateinit var profileSwitch: List<ProfileSwitch>
|
||||
private lateinit var profileSwitch: List<EffectiveProfileSwitch>
|
||||
private val profileSwitchUsed = arrayOf(0, 0)
|
||||
|
||||
private lateinit var binding: ActivityProfilehelperBinding
|
||||
|
@ -98,7 +98,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
// Active profile
|
||||
profileList = activePlugin.activeProfileInterface.profile?.getProfileList() ?: ArrayList()
|
||||
profileList = activePlugin.activeProfileSource.profile?.getProfileList() ?: ArrayList()
|
||||
|
||||
binding.availableProfileList.setOnClickListener {
|
||||
PopupMenu(this, binding.availableProfileList).apply {
|
||||
|
@ -114,12 +114,12 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
}
|
||||
|
||||
// Profile switch
|
||||
profileSwitch = databaseHelper.getProfileSwitchData(dateUtil._now() - T.months(2).msecs(), true)
|
||||
profileSwitch = repository.getEffectiveProfileSwitchDataFromTime(dateUtil.now() - T.months(2).msecs(), true).blockingGet()
|
||||
|
||||
binding.profileswitchList.setOnClickListener {
|
||||
PopupMenu(this, binding.profileswitchList).apply {
|
||||
var order = 0
|
||||
for (name in profileSwitch) menu.add(Menu.NONE, order, order++, name.customizedName)
|
||||
for (name in profileSwitch) menu.add(Menu.NONE, order, order++, name.originalCustomizedName)
|
||||
setOnMenuItemClickListener { item ->
|
||||
binding.profileswitchList.setText(item.title)
|
||||
profileSwitchUsed[tabSelected] = item.itemId
|
||||
|
@ -131,6 +131,7 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
// Default profile
|
||||
binding.copytolocalprofile.setOnClickListener {
|
||||
storeValues()
|
||||
val age = ageUsed[tabSelected]
|
||||
val weight = weightUsed[tabSelected]
|
||||
val tdd = tddUsed[tabSelected]
|
||||
|
@ -138,8 +139,14 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
val profile = if (typeSelected[tabSelected] == ProfileType.MOTOL_DEFAULT) defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
|
||||
else defaultProfileDPV.profile(age, tdd, pct / 100.0, profileFunction.getUnits())
|
||||
profile?.let {
|
||||
OKDialog.showConfirmation(this, resourceHelper.gs(R.string.careportal_profileswitch), resourceHelper.gs(R.string.copytolocalprofile), Runnable {
|
||||
localProfilePlugin.addProfile(localProfilePlugin.copyFrom(it, "DefaultProfile" + dateUtil.dateAndTimeAndSecondsString(dateUtil._now())))
|
||||
OKDialog.showConfirmation(this, rh.gs(R.string.careportal_profileswitch), rh.gs(R.string.copytolocalprofile), Runnable {
|
||||
localProfilePlugin.addProfile(
|
||||
localProfilePlugin.copyFrom(
|
||||
it, "DefaultProfile " +
|
||||
dateUtil.dateAndTimeAndSecondsString(dateUtil.now())
|
||||
.replace(".", "/")
|
||||
)
|
||||
)
|
||||
rxBus.send(EventLocalProfileChanged())
|
||||
})
|
||||
}
|
||||
|
@ -163,7 +170,12 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
binding.basalpctfromtdd.setParams(32.0, 32.0, 37.0, 1.0, DecimalFormat("0"), false, null)
|
||||
|
||||
binding.tdds.text = tddCalculator.stats()
|
||||
@SuppressLint("SetTextI18n")
|
||||
binding.tdds.text = getString(R.string.tdd) + ": " + rh.gs(R.string.calculation_in_progress)
|
||||
Thread {
|
||||
val tdds = tddCalculator.stats()
|
||||
runOnUiThread { binding.tdds.text = tdds }
|
||||
}.start()
|
||||
|
||||
// Current profile
|
||||
binding.currentProfileText.text = profileFunction.getProfileName()
|
||||
|
@ -206,12 +218,20 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
getProfile(ageUsed[1], tddUsed[1], weightUsed[1], pctUsed[1] / 100.0, 1)?.let { profile1 ->
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
pvd.arguments = Bundle().also {
|
||||
it.putLong("time", DateUtil.now())
|
||||
it.putLong("time", dateUtil.now())
|
||||
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
|
||||
it.putString("customProfile", profile0.data.toString())
|
||||
it.putString("customProfile2", profile1.data.toString())
|
||||
it.putString("customProfileUnits", profileFunction.getUnits())
|
||||
it.putString("customProfileName", getProfileName(ageUsed[0], tddUsed[0], weightUsed[0], pctUsed[0] / 100.0, 0) + "\n" + getProfileName(ageUsed[1], tddUsed[1], weightUsed[1], pctUsed[1] / 100.0, 1))
|
||||
it.putString("customProfile", profile0.jsonObject.toString())
|
||||
it.putString("customProfile2", profile1.jsonObject.toString())
|
||||
it.putString(
|
||||
"customProfileName",
|
||||
getProfileName(ageUsed[0], tddUsed[0], weightUsed[0], pctUsed[0] / 100.0, 0) + "\n" + getProfileName(
|
||||
ageUsed[1],
|
||||
tddUsed[1],
|
||||
weightUsed[1],
|
||||
pctUsed[1] / 100.0,
|
||||
1
|
||||
)
|
||||
)
|
||||
}
|
||||
}.show(supportFragmentManager, "ProfileViewDialog")
|
||||
return@setOnClickListener
|
||||
|
@ -223,14 +243,14 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
switchTab(0, typeSelected[0], false)
|
||||
}
|
||||
|
||||
private fun getProfile(age: Double, tdd: Double, weight: Double, basalPct: Double, tab: Int): Profile? =
|
||||
private fun getProfile(age: Double, tdd: Double, weight: Double, basalPct: Double, tab: Int): PureProfile? =
|
||||
try { // profile must not exist
|
||||
when (typeSelected[tab]) {
|
||||
ProfileType.MOTOL_DEFAULT -> defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
|
||||
ProfileType.DPV_DEFAULT -> defaultProfileDPV.profile(age, tdd, basalPct, profileFunction.getUnits())
|
||||
ProfileType.CURRENT -> profileFunction.getProfile()?.convertToNonCustomizedProfile()
|
||||
ProfileType.AVAILABLE_PROFILE -> activePlugin.activeProfileInterface.profile?.getSpecificProfile(profileList[profileUsed[tab]].toString())
|
||||
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].profileObject?.convertToNonCustomizedProfile()
|
||||
ProfileType.CURRENT -> profileFunction.getProfile()?.convertToNonCustomizedProfile(dateUtil)
|
||||
ProfileType.AVAILABLE_PROFILE -> activePlugin.activeProfileSource.profile?.getSpecificProfile(profileList[profileUsed[tab]].toString())
|
||||
ProfileType.PROFILE_SWITCH -> ProfileSealed.EPS(profileSwitch[profileSwitchUsed[tab]]).convertToNonCustomizedProfile(dateUtil)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
|
@ -238,11 +258,11 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
private fun getProfileName(age: Double, tdd: Double, weight: Double, basalSumPct: Double, tab: Int): String =
|
||||
when (typeSelected[tab]) {
|
||||
ProfileType.MOTOL_DEFAULT -> if (tdd > 0) resourceHelper.gs(R.string.formatwithtdd, age, tdd) else resourceHelper.gs(R.string.formatwithweight, age, weight)
|
||||
ProfileType.DPV_DEFAULT -> resourceHelper.gs(R.string.formatwittddandpct, age, tdd, (basalSumPct * 100).toInt())
|
||||
ProfileType.MOTOL_DEFAULT -> if (tdd > 0) rh.gs(R.string.formatwithtdd, age, tdd) else rh.gs(R.string.formatwithweight, age, weight)
|
||||
ProfileType.DPV_DEFAULT -> rh.gs(R.string.formatwittddandpct, age, tdd, (basalSumPct * 100).toInt())
|
||||
ProfileType.CURRENT -> profileFunction.getProfileName()
|
||||
ProfileType.AVAILABLE_PROFILE -> profileList[profileUsed[tab]].toString()
|
||||
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].customizedName
|
||||
ProfileType.PROFILE_SWITCH -> profileSwitch[profileSwitchUsed[tab]].originalCustomizedName
|
||||
}
|
||||
|
||||
private fun storeValues() {
|
||||
|
@ -259,17 +279,18 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
tabSelected = tab
|
||||
typeSelected[tabSelected] = newContent
|
||||
binding.profiletypeTitle.defaultHintTextColor = ColorStateList.valueOf(resourceHelper.gc(if (tab == 0) R.color.tabBgColorSelected else R.color.examinedProfile))
|
||||
binding.profiletypeTitle.defaultHintTextColor = ColorStateList.valueOf(rh.gc(if (tab == 0) R.color.tabBgColorSelected else R.color.examinedProfile))
|
||||
|
||||
// show new content
|
||||
binding.profiletype.setText(
|
||||
when (typeSelected[tabSelected]) {
|
||||
ProfileType.MOTOL_DEFAULT -> resourceHelper.gs(R.string.motoldefaultprofile)
|
||||
ProfileType.DPV_DEFAULT -> resourceHelper.gs(R.string.dpvdefaultprofile)
|
||||
ProfileType.CURRENT -> resourceHelper.gs(R.string.currentprofile)
|
||||
ProfileType.AVAILABLE_PROFILE -> resourceHelper.gs(R.string.availableprofile)
|
||||
ProfileType.PROFILE_SWITCH -> resourceHelper.gs(R.string.careportal_profileswitch)
|
||||
})
|
||||
ProfileType.MOTOL_DEFAULT -> rh.gs(R.string.motoldefaultprofile)
|
||||
ProfileType.DPV_DEFAULT -> rh.gs(R.string.dpvdefaultprofile)
|
||||
ProfileType.CURRENT -> rh.gs(R.string.currentprofile)
|
||||
ProfileType.AVAILABLE_PROFILE -> rh.gs(R.string.availableprofile)
|
||||
ProfileType.PROFILE_SWITCH -> rh.gs(R.string.careportal_profileswitch)
|
||||
}
|
||||
)
|
||||
binding.defaultProfile.visibility = (newContent == ProfileType.MOTOL_DEFAULT || newContent == ProfileType.DPV_DEFAULT).toVisibility()
|
||||
binding.currentProfile.visibility = (newContent == ProfileType.CURRENT).toVisibility()
|
||||
binding.availableProfile.visibility = (newContent == ProfileType.AVAILABLE_PROFILE).toVisibility()
|
||||
|
@ -285,11 +306,11 @@ class ProfileHelperActivity : NoSplashAppCompatActivity() {
|
|||
if (profileList.isNotEmpty())
|
||||
binding.availableProfileList.setText(profileList[profileUsed[tabSelected]].toString())
|
||||
if (profileSwitch.isNotEmpty())
|
||||
binding.profileswitchList.setText(profileSwitch[profileSwitchUsed[tabSelected]].customizedName)
|
||||
binding.profileswitchList.setText(profileSwitch[profileSwitchUsed[tabSelected]].originalCustomizedName)
|
||||
}
|
||||
|
||||
private fun setBackgroundColorOnSelected(tab: Int) {
|
||||
binding.menu1.setBackgroundColor(resourceHelper.gc(if (tab == 1) R.color.defaultbackground else R.color.tabBgColorSelected))
|
||||
binding.menu2.setBackgroundColor(resourceHelper.gc(if (tab == 0) R.color.defaultbackground else R.color.examinedProfile))
|
||||
binding.menu1.setBackgroundColor(rh.gc(if (tab == 1) R.color.defaultbackground else R.color.tempbasal))
|
||||
binding.menu2.setBackgroundColor(rh.gc(if (tab == 0) R.color.defaultbackground else R.color.examinedProfile))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import javax.inject.Inject
|
|||
class RequestDexcomPermissionActivity : DialogAppCompatActivity() {
|
||||
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
||||
|
||||
private val requestCode = "AndroidAPS <3".map { it.toInt() }.sum()
|
||||
private val requestCode = "AndroidAPS <3".map { it.code }.sum()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
|
|
@ -19,7 +19,7 @@ class SingleFragmentActivity : DaggerAppCompatActivityWithResult() {
|
|||
|
||||
private var plugin: PluginBase? = null
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_single_fragment)
|
||||
plugin = pluginStore.plugins[intent.getIntExtra("plugin", -1)]
|
||||
|
@ -52,7 +52,7 @@ class SingleFragmentActivity : DaggerAppCompatActivityWithResult() {
|
|||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
public override fun attachBaseContext(newBase: Context) {
|
||||
override fun attachBaseContext(newBase: Context) {
|
||||
super.attachBaseContext(LocaleHelper.wrap(newBase))
|
||||
}
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.ActivityStatsBinding
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||
import info.nightscout.androidaps.utils.stats.TirCalculator
|
||||
import javax.inject.Inject
|
||||
|
@ -14,21 +19,37 @@ class StatsActivity : NoSplashAppCompatActivity() {
|
|||
@Inject lateinit var tddCalculator: TddCalculator
|
||||
@Inject lateinit var tirCalculator: TirCalculator
|
||||
@Inject lateinit var activityMonitor: ActivityMonitor
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
private lateinit var binding: ActivityStatsBinding
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityStatsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.tdds.text = tddCalculator.stats()
|
||||
binding.tir.text = tirCalculator.stats()
|
||||
binding.activity.text = activityMonitor.stats()
|
||||
binding.tdds.text = getString(R.string.tdd) + ": " + rh.gs(R.string.calculation_in_progress)
|
||||
binding.tir.text = getString(R.string.tir) + ": " + rh.gs(R.string.calculation_in_progress)
|
||||
binding.activity.text = rh.gs(R.string.activitymonitor) + ": " + rh.gs(R.string.calculation_in_progress)
|
||||
|
||||
Thread {
|
||||
val tdds = tddCalculator.stats()
|
||||
runOnUiThread { binding.tdds.text = tdds }
|
||||
}.start()
|
||||
Thread {
|
||||
val tir = tirCalculator.stats()
|
||||
runOnUiThread { binding.tir.text = tir }
|
||||
}.start()
|
||||
Thread {
|
||||
val activity = activityMonitor.stats()
|
||||
runOnUiThread { binding.activity.text = activity }
|
||||
}.start()
|
||||
|
||||
binding.ok.setOnClickListener { finish() }
|
||||
binding.reset.setOnClickListener {
|
||||
OKDialog.showConfirmation(this, resourceHelper.gs(R.string.doyouwantresetstats)) {
|
||||
OKDialog.showConfirmation(this, rh.gs(R.string.doyouwantresetstats)) {
|
||||
uel.log(Action.STAT_RESET, Sources.Stats)
|
||||
activityMonitor.reset()
|
||||
recreate()
|
||||
}
|
||||
|
|
|
@ -5,31 +5,30 @@ import android.widget.ArrayAdapter
|
|||
import com.google.firebase.auth.FirebaseAuth
|
||||
import com.google.firebase.database.FirebaseDatabase
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.databinding.ActivitySurveyBinding
|
||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.InstanceId
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||
import info.nightscout.androidaps.utils.stats.TirCalculator
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import javax.inject.Inject
|
||||
|
||||
class SurveyActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var tddCalculator: TddCalculator
|
||||
@Inject lateinit var tirCalculator: TirCalculator
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var activityMonitor: ActivityMonitor
|
||||
@Inject lateinit var defaultProfile: DefaultProfile
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
private lateinit var binding: ActivitySurveyBinding
|
||||
|
||||
|
@ -40,7 +39,7 @@ class SurveyActivity : NoSplashAppCompatActivity() {
|
|||
|
||||
binding.id.text = InstanceId.instanceId()
|
||||
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
val profileList = profileStore?.getProfileList() ?: return
|
||||
binding.spinner.adapter = ArrayAdapter(this, R.layout.spinner_centered, profileList)
|
||||
|
||||
|
@ -68,11 +67,10 @@ class SurveyActivity : NoSplashAppCompatActivity() {
|
|||
defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())?.let { profile ->
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
pvd.arguments = Bundle().also {
|
||||
it.putLong("time", DateUtil.now())
|
||||
it.putLong("time", dateUtil.now())
|
||||
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
|
||||
it.putString("customProfile", runningProfile.data.toString())
|
||||
it.putString("customProfile2", profile.data.toString())
|
||||
it.putString("customProfileUnits", profile.units)
|
||||
it.putString("customProfile", runningProfile.toPureNsJson(dateUtil).toString())
|
||||
it.putString("customProfile2", profile.jsonObject.toString())
|
||||
it.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
|
||||
}
|
||||
}.show(supportFragmentManager, "ProfileViewDialog")
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
package info.nightscout.androidaps.activities
|
||||
|
||||
import android.os.Bundle
|
||||
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
|
||||
|
||||
class TreatmentsActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
|
||||
private lateinit var binding: TreatmentsFragmentBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
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)
|
||||
}
|
||||
binding.extendedBoluses.setOnClickListener {
|
||||
setFragment(TreatmentsExtendedBolusesFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
binding.tempBasals.setOnClickListener {
|
||||
setFragment(TreatmentsTemporaryBasalsFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
binding.tempTargets.setOnClickListener {
|
||||
setFragment(TreatmentsTempTargetFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
binding.profileSwitches.setOnClickListener {
|
||||
setFragment(TreatmentsProfileSwitchFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
binding.careportal.setOnClickListener {
|
||||
setFragment(TreatmentsCareportalFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
binding.userentry.setOnClickListener {
|
||||
setFragment(TreatmentsUserEntryFragment())
|
||||
setBackgroundColorOnSelected(it)
|
||||
}
|
||||
setFragment(TreatmentsBolusCarbsFragment())
|
||||
setBackgroundColorOnSelected(binding.treatments)
|
||||
}
|
||||
|
||||
private fun setFragment(selectedFragment: Fragment) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.replace(R.id.fragment_container, selectedFragment)
|
||||
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
|
||||
.commit()
|
||||
}
|
||||
|
||||
private fun setBackgroundColorOnSelected(selected: View) {
|
||||
binding.treatments.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.extendedBoluses.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.tempBasals.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.tempTargets.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.profileSwitches.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.careportal.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
binding.userentry.setBackgroundColor(rh.gc(R.color.defaultbackground))
|
||||
selected.setBackgroundColor(rh.gc(R.color.tabBgColorSelected))
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,400 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.Bolus
|
||||
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.androidaps.database.entities.Carbs
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.CutCarbsTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateBolusCalculatorResultTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateBolusTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateCarbsTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsBolusCarbsItemBinding
|
||||
import info.nightscout.androidaps.dialogs.WizardInfoDialog
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventTreatmentChange
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.extensions.iobCalc
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
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.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsBolusCarbsFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
|
||||
class MealLink(
|
||||
val bolus: Bolus? = null,
|
||||
val carbs: Carbs? = null,
|
||||
val bolusCalculatorResult: BolusCalculatorResult? = null
|
||||
)
|
||||
|
||||
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!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsBolusCarbsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
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
|
||||
.getBolusesIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.map { bolus -> bolus.map { MealLink(bolus = it) } }
|
||||
|
||||
private fun carbsMealLinksWithInvalid(now: Long) = repository
|
||||
.getCarbsIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.map { carb -> carb.map { MealLink(carbs = it) } }
|
||||
|
||||
private fun calcResultMealLinksWithInvalid(now: Long) = repository
|
||||
.getBolusCalculatorResultsIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.map { calc -> calc.map { MealLink(bolusCalculatorResult = it) } }
|
||||
|
||||
private fun bolusMealLinks(now: Long) = repository
|
||||
.getBolusesDataFromTime(now - millsToThePast, false)
|
||||
.map { bolus -> bolus.map { MealLink(bolus = it) } }
|
||||
|
||||
private fun carbsMealLinks(now: Long) = repository
|
||||
.getCarbsDataFromTime(now - millsToThePast, false)
|
||||
.map { carb -> carb.map { MealLink(carbs = it) } }
|
||||
|
||||
private fun calcResultMealLinks(now: Long) = repository
|
||||
.getBolusCalculatorResultsDataFromTime(now - millsToThePast, false)
|
||||
.map { calc -> calc.map { MealLink(bolusCalculatorResult = it) } }
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += carbsMealLinksWithInvalid(now)
|
||||
.zipWith(bolusMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinksWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
ml.sortedByDescending {
|
||||
it.carbs?.timestamp ?: it.bolus?.timestamp
|
||||
?: it.bolusCalculatorResult?.timestamp
|
||||
}
|
||||
}
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
else
|
||||
disposable += carbsMealLinks(now)
|
||||
.zipWith(bolusMealLinks(now)) { first, second -> first + second }
|
||||
.zipWith(calcResultMealLinks(now)) { first, second -> first + second }
|
||||
.map { ml ->
|
||||
ml.sortedByDescending {
|
||||
it.carbs?.timestamp ?: it.bolus?.timestamp
|
||||
?: it.bolusCalculatorResult?.timestamp
|
||||
}
|
||||
}
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true)
|
||||
binding.deleteFutureTreatments.visibility = list.isNotEmpty().toVisibility()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentChange::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(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))
|
||||
|
||||
override fun onBindViewHolder(holder: MealLinkLoadedViewHolder, position: Int) {
|
||||
val profile = profileFunction.getProfile() ?: return
|
||||
val ml = mealLinks[position]
|
||||
|
||||
// Metadata
|
||||
holder.binding.metadataLayout.visibility = (ml.bolusCalculatorResult != null && (ml.bolusCalculatorResult.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
ml.bolusCalculatorResult?.let { bolusCalculatorResult ->
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(bolusCalculatorResult.timestamp)
|
||||
}
|
||||
|
||||
// Bolus
|
||||
holder.binding.bolusLayout.visibility = (ml.bolus != null && (ml.bolus.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
ml.bolus?.let { bolus ->
|
||||
holder.binding.bolusDate.text = dateUtil.timeString(bolus.timestamp)
|
||||
holder.binding.insulin.text = rh.gs(R.string.formatinsulinunits, bolus.amount)
|
||||
holder.binding.bolusNs.visibility = (bolus.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.bolusPump.visibility = (bolus.interfaceIDs.pumpId != null).toVisibility()
|
||||
holder.binding.bolusInvalid.visibility = bolus.isValid.not().toVisibility()
|
||||
val iob = bolus.iobCalc(activePlugin, System.currentTimeMillis(), profile.dia)
|
||||
if (iob.iobContrib > 0.01) {
|
||||
holder.binding.iob.setTextColor(rh.gc(R.color.colorActive))
|
||||
holder.binding.iob.text = rh.gs(R.string.formatinsulinunits, iob.iobContrib)
|
||||
holder.binding.iobLabel.visibility = View.VISIBLE
|
||||
holder.binding.iob.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.binding.iob.text = rh.gs(R.string.formatinsulinunits, 0.0)
|
||||
holder.binding.iob.setTextColor(holder.binding.insulin.currentTextColor)
|
||||
holder.binding.iobLabel.visibility = View.GONE
|
||||
holder.binding.iob.visibility = View.GONE
|
||||
}
|
||||
if (bolus.timestamp > dateUtil.now()) holder.binding.date.setTextColor(rh.gc(R.color.colorScheduled)) else holder.binding.date.setTextColor(holder.binding.carbs.currentTextColor)
|
||||
holder.binding.mealOrCorrection.text =
|
||||
when (ml.bolus.type) {
|
||||
Bolus.Type.SMB -> "SMB"
|
||||
Bolus.Type.NORMAL -> rh.gs(R.string.mealbolus)
|
||||
Bolus.Type.PRIMING -> rh.gs(R.string.prime)
|
||||
}
|
||||
}
|
||||
// Carbs
|
||||
holder.binding.carbsLayout.visibility = (ml.carbs != null && (ml.carbs.isValid || binding.showInvalidated.isChecked)).toVisibility()
|
||||
ml.carbs?.let { carbs ->
|
||||
holder.binding.carbsDate.text = dateUtil.timeString(carbs.timestamp)
|
||||
holder.binding.carbs.text = rh.gs(R.string.format_carbs, carbs.amount.toInt())
|
||||
holder.binding.carbsDuration.text = if (carbs.duration > 0) rh.gs(R.string.format_mins, T.msecs(carbs.duration).mins().toInt()) else ""
|
||||
holder.binding.carbsNs.visibility = (carbs.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
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.calculation.tag = ml
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mealLinks.size
|
||||
}
|
||||
|
||||
inner class MealLinkLoadedViewHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
val binding = TreatmentsBolusCarbsItemBinding.bind(view)
|
||||
|
||||
init {
|
||||
binding.calculation.setOnClickListener {
|
||||
val mealLinkLoaded = it.tag as MealLink? ?: return@setOnClickListener
|
||||
mealLinkLoaded.bolusCalculatorResult?.let { bolusCalculatorResult ->
|
||||
WizardInfoDialog().also { wizardDialog ->
|
||||
wizardDialog.setData(bolusCalculatorResult)
|
||||
wizardDialog.show(childFragmentManager, "WizardInfoDialog")
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.calculation.paintFlags = binding.calculation.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
binding.bolusRemove.setOnClickListener { ml ->
|
||||
val bolus = (ml.tag as MealLink?)?.bolus ?: return@setOnClickListener
|
||||
activity?.let { activity ->
|
||||
val text = 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 {
|
||||
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 {
|
||||
uel.log(
|
||||
Action.CARBS_REMOVED, Sources.Treatments,
|
||||
ValueWithUnit.Timestamp(carb.timestamp),
|
||||
ValueWithUnit.Gram(carb.amount.toInt())
|
||||
)
|
||||
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) }
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.carbsRemove.paintFlags = binding.carbsRemove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateAAPSStartedTherapyEventTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateTherapyEventTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsCareportalFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsCareportalItemBinding
|
||||
import info.nightscout.androidaps.events.EventTherapyEventChange
|
||||
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.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsCareportalFragment.RecyclerViewAdapter.TherapyEventsViewHolder
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.Translator
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsCareportalFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var translator: Translator
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@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.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
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)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.refreshFromNightscout.setOnClickListener {
|
||||
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)
|
||||
disposable += Completable.fromAction { repository.deleteAllTherapyEventsEntries() }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTherapyEventChange()) }
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
})
|
||||
}
|
||||
}
|
||||
binding.removeAndroidapsStartedEvents.setOnClickListener {
|
||||
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)))
|
||||
.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)
|
||||
repository
|
||||
.getTherapyEventDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getTherapyEventDataFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
disposable += rxBus
|
||||
.toObservable(EventTherapyEventChange::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(private var list: List<TherapyEvent>) : RecyclerView.Adapter<TherapyEventsViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TherapyEventsViewHolder {
|
||||
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_careportal_item, viewGroup, false)
|
||||
return TherapyEventsViewHolder(v)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TherapyEventsViewHolder, position: Int) {
|
||||
val therapyEvent = list[position]
|
||||
holder.binding.ns.visibility = (therapyEvent.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = therapyEvent.isValid.not().toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(therapyEvent.timestamp)
|
||||
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
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.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" +
|
||||
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 ,
|
||||
ValueWithUnit.Timestamp(therapyEvent.timestamp),
|
||||
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)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,178 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.interfaces.end
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateExtendedBolusTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsExtendedbolusItemBinding
|
||||
import info.nightscout.androidaps.events.EventExtendedBolusChange
|
||||
import info.nightscout.androidaps.extensions.iobCalc
|
||||
import info.nightscout.androidaps.extensions.isInProgress
|
||||
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.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 io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsExtendedBolusesFragment : DaggerFragment() {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private var _binding: TreatmentsExtendedbolusFragmentBinding? = 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 =
|
||||
TreatmentsExtendedbolusFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showInvalidated.isChecked)
|
||||
repository
|
||||
.getExtendedBolusDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getExtendedBolusDataFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventExtendedBolusChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private inner class RecyclerViewAdapter(private var extendedBolusList: List<ExtendedBolus>) : RecyclerView.Adapter<ExtendedBolusesViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ExtendedBolusesViewHolder {
|
||||
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_extendedbolus_item, viewGroup, false)
|
||||
return ExtendedBolusesViewHolder(v)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ExtendedBolusesViewHolder, position: Int) {
|
||||
val extendedBolus = extendedBolusList[position]
|
||||
holder.binding.ns.visibility = (extendedBolus.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.ph.visibility = (extendedBolus.interfaceIDs.pumpId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = extendedBolus.isValid.not().toVisibility()
|
||||
@SuppressLint("SetTextI18n")
|
||||
if (extendedBolus.isInProgress(dateUtil)) {
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(extendedBolus.timestamp)
|
||||
holder.binding.date.setTextColor(rh.gc(R.color.colorActive))
|
||||
} else {
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(extendedBolus.timestamp) + " - " + dateUtil.timeString(extendedBolus.end)
|
||||
holder.binding.date.setTextColor(holder.binding.insulin.currentTextColor)
|
||||
}
|
||||
val profile = profileFunction.getProfile(extendedBolus.timestamp) ?: return
|
||||
holder.binding.duration.text = rh.gs(R.string.format_mins, T.msecs(extendedBolus.duration).mins())
|
||||
holder.binding.insulin.text = rh.gs(R.string.formatinsulinunits, extendedBolus.amount)
|
||||
val iob = extendedBolus.iobCalc(System.currentTimeMillis(), profile, activePlugin.activeInsulin)
|
||||
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
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 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,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateProfileSwitchTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsProfileswitchFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsProfileswitchItemBinding
|
||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||
import info.nightscout.androidaps.events.EventProfileSwitchChanged
|
||||
import info.nightscout.androidaps.extensions.getCustomizedName
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
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.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsProfileSwitchFragment.RecyclerProfileViewAdapter.ProfileSwitchViewHolder
|
||||
import info.nightscout.androidaps.events.EventEffectiveProfileSwitchChanged
|
||||
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.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsProfileSwitchFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var localProfilePlugin: LocalProfilePlugin
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
private var _binding: TreatmentsProfileswitchFragmentBinding? = null
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
|
||||
// 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)
|
||||
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.deleteAllEffectiveProfileSwitches()
|
||||
repository.deleteAllProfileSwitches()
|
||||
}
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = {
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(0L))
|
||||
rxBus.send(EventNewHistoryData(0, false))
|
||||
}
|
||||
)
|
||||
rxBus.send(EventNSClientRestart())
|
||||
}
|
||||
}
|
||||
}
|
||||
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)
|
||||
.map { bolus -> bolus.map { ProfileSealed.PS(it) } }
|
||||
|
||||
private fun effectiveProfileSwitchWithInvalid(now: Long) = repository
|
||||
.getEffectiveProfileSwitchDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.map { carb -> carb.map { ProfileSealed.EPS(it) } }
|
||||
|
||||
private fun profileSwitches(now: Long) = repository
|
||||
.getProfileSwitchDataFromTime(now - millsToThePast, false)
|
||||
.map { bolus -> bolus.map { ProfileSealed.PS(it) } }
|
||||
|
||||
private fun effectiveProfileSwitches(now: Long) = repository
|
||||
.getEffectiveProfileSwitchDataFromTime(now - millsToThePast, false)
|
||||
.map { carb -> carb.map { ProfileSealed.EPS(it) } }
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
|
||||
if (binding.showInvalidated.isChecked)
|
||||
disposable += profileSwitchWithInvalid(now)
|
||||
.zipWith(effectiveProfileSwitchWithInvalid(now)) { first, second -> first + second }
|
||||
.map { ml -> ml.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list ->
|
||||
binding.recyclerview.swapAdapter(RecyclerProfileViewAdapter(list), true)
|
||||
}
|
||||
else
|
||||
disposable += 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
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
disposable += rxBus
|
||||
.toObservable(EventProfileSwitchChanged::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
disposable += rxBus
|
||||
.toObservable(EventEffectiveProfileSwitchChanged::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
inner class RecyclerProfileViewAdapter(private var profileSwitchList: List<ProfileSealed>) : RecyclerView.Adapter<ProfileSwitchViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ProfileSwitchViewHolder =
|
||||
ProfileSwitchViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_profileswitch_item, viewGroup, false))
|
||||
|
||||
override fun onBindViewHolder(holder: ProfileSwitchViewHolder, position: Int) {
|
||||
val profileSwitch = profileSwitchList[position]
|
||||
holder.binding.ph.visibility = (profileSwitch is ProfileSealed.EPS).toVisibility()
|
||||
holder.binding.ns.visibility = (profileSwitch.interfaceIDs_backing?.nightscoutId != null).toVisibility()
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(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 ""
|
||||
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.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))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return 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,
|
||||
profileSwitch.getCustomizedName() + " " + dateUtil.dateAndTimeString(profileSwitch.timestamp).replace(".", "_"),
|
||||
ValueWithUnit.Timestamp(profileSwitch.timestamp),
|
||||
ValueWithUnit.SimpleString(profileSwitch.profileName))
|
||||
val nonCustomized = profileSealed.convertToNonCustomizedProfile(dateUtil)
|
||||
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 ->
|
||||
pvd.arguments = Bundle().also { args ->
|
||||
args.putLong("time", (it.tag as ProfileSealed).timestamp)
|
||||
args.putInt("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal)
|
||||
}
|
||||
pvd.show(childFragmentManager, "ProfileViewDialog")
|
||||
}
|
||||
}
|
||||
binding.date.setOnClickListener {
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
pvd.arguments = Bundle().also { args ->
|
||||
args.putLong("time", (it.tag as ProfileSealed).timestamp)
|
||||
args.putInt("mode", ProfileViewerDialog.Mode.RUNNING_PROFILE.ordinal)
|
||||
}
|
||||
pvd.show(childFragmentManager, "ProfileViewDialog")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.interfaces.end
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateTemporaryTargetTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsTemptargetFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsTemptargetItemBinding
|
||||
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||
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.plugins.general.nsclient.events.EventNSClientRestart
|
||||
import info.nightscout.androidaps.events.EventTreatmentUpdateGui
|
||||
import info.nightscout.androidaps.activities.fragments.TreatmentsTempTargetFragment.RecyclerViewAdapter.TempTargetsViewHolder
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.Translator
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
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.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.Completable
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import io.reactivex.rxkotlin.subscribeBy
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsTempTargetFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var translator: Translator
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@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.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
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)
|
||||
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() }
|
||||
.subscribeOn(aapsSchedulers.io)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribeBy(
|
||||
onError = { aapsLogger.error("Error removing entries", it) },
|
||||
onComplete = { rxBus.send(EventTempTargetChange()) }
|
||||
)
|
||||
|
||||
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)
|
||||
repository
|
||||
.getTemporaryTargetDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
repository
|
||||
.getTemporaryTargetDataFromTime(now - millsToThePast, false)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventTempTargetChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java) // TODO join with above
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private inner class RecyclerViewAdapter(private var tempTargetList: List<TemporaryTarget>) : RecyclerView.Adapter<TempTargetsViewHolder>() {
|
||||
|
||||
private val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||
private val currentlyActiveTarget = if (dbRecord is ValueWrapper.Existing) dbRecord.value else null
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TempTargetsViewHolder =
|
||||
TempTargetsViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_temptarget_item, viewGroup, false))
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun onBindViewHolder(holder: TempTargetsViewHolder, position: Int) {
|
||||
val units = profileFunction.getUnits()
|
||||
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.date.text = dateUtil.dateAndTimeString(tempTarget.timestamp) + " - " + dateUtil.timeString(tempTarget.end)
|
||||
holder.binding.duration.text = rh.gs(R.string.format_mins, T.msecs(tempTarget.duration).mins())
|
||||
holder.binding.low.text = tempTarget.lowValueToUnitsToString(units)
|
||||
holder.binding.high.text = tempTarget.highValueToUnitsToString(units)
|
||||
holder.binding.reason.text = translator.translate(tempTarget.reason)
|
||||
holder.binding.date.setTextColor(
|
||||
when {
|
||||
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
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 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,
|
||||
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()))
|
||||
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)
|
||||
}
|
||||
}
|
||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
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 androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.database.entities.ExtendedBolus
|
||||
import info.nightscout.androidaps.database.entities.TemporaryBasal
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.*
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.interfaces.end
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateExtendedBolusTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InvalidateTemporaryBasalTransaction
|
||||
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsTempbasalsItemBinding
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventTempBasalChange
|
||||
import info.nightscout.androidaps.extensions.iobCalc
|
||||
import info.nightscout.androidaps.extensions.toStringFull
|
||||
import info.nightscout.androidaps.extensions.toTemporaryBasal
|
||||
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.TreatmentsTemporaryBasalsFragment.RecyclerViewAdapter.TempBasalsViewHolder
|
||||
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 io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
||||
class TreatmentsTemporaryBasalsFragment : DaggerFragment() {
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private var _binding: TreatmentsTempbasalsFragmentBinding? = null
|
||||
|
||||
private val millsToThePast = T.days(30).msecs()
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View =
|
||||
TreatmentsTempbasalsFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
}
|
||||
|
||||
private fun tempBasalsWithInvalid(now: Long) = repository
|
||||
.getTemporaryBasalsDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
|
||||
private fun tempBasals(now: Long) = repository
|
||||
.getTemporaryBasalsDataFromTime(now - millsToThePast, false)
|
||||
|
||||
private fun extendedBolusesWithInvalid(now: Long) = repository
|
||||
.getExtendedBolusDataIncludingInvalidFromTime(now - millsToThePast, false)
|
||||
.map { eb -> eb.map { profileFunction.getProfile(it.timestamp)?.let { profile -> it.toTemporaryBasal(profile) } } }
|
||||
|
||||
private fun extendedBoluses(now: Long) = repository
|
||||
.getExtendedBolusDataFromTime(now - millsToThePast, false)
|
||||
.map { eb -> eb.map { profileFunction.getProfile(it.timestamp)?.let { profile -> it.toTemporaryBasal(profile) } } }
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
disposable +=
|
||||
if (activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
tempBasalsWithInvalid(now)
|
||||
.zipWith(extendedBolusesWithInvalid(now)) { first, second -> first + second }
|
||||
.map { list -> list.filterNotNull() }
|
||||
.map { list -> list.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
tempBasals(now)
|
||||
.zipWith(extendedBoluses(now)) { first, second -> first + second }
|
||||
.map { list -> list.filterNotNull() }
|
||||
.map { list -> list.sortedByDescending { it.timestamp } }
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
} else {
|
||||
if (binding.showInvalidated.isChecked)
|
||||
tempBasalsWithInvalid(now)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
else
|
||||
tempBasals(now)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventTempBasalChange::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
binding.recyclerview.adapter = null // avoid leaks
|
||||
_binding = null
|
||||
}
|
||||
|
||||
inner class RecyclerViewAdapter internal constructor(private var tempBasalList: List<TemporaryBasal>) : RecyclerView.Adapter<TempBasalsViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): TempBasalsViewHolder =
|
||||
TempBasalsViewHolder(LayoutInflater.from(viewGroup.context).inflate(R.layout.treatments_tempbasals_item, viewGroup, false))
|
||||
|
||||
override fun onBindViewHolder(holder: TempBasalsViewHolder, position: Int) {
|
||||
val tempBasal = tempBasalList[position]
|
||||
holder.binding.ns.visibility = (tempBasal.interfaceIDs.nightscoutId != null).toVisibility()
|
||||
holder.binding.invalid.visibility = tempBasal.isValid.not().toVisibility()
|
||||
holder.binding.ph.visibility = (tempBasal.interfaceIDs.pumpId != null).toVisibility()
|
||||
if (tempBasal.isInProgress) {
|
||||
holder.binding.date.text = dateUtil.dateAndTimeString(tempBasal.timestamp)
|
||||
holder.binding.date.setTextColor(rh.gc(R.color.colorActive))
|
||||
} else {
|
||||
holder.binding.date.text = dateUtil.dateAndTimeRangeString(tempBasal.timestamp, tempBasal.end)
|
||||
holder.binding.date.setTextColor(holder.binding.duration.currentTextColor)
|
||||
}
|
||||
holder.binding.duration.text = rh.gs(R.string.format_mins, T.msecs(tempBasal.duration).mins())
|
||||
if (tempBasal.isAbsolute) holder.binding.rate.text = rh.gs(R.string.pump_basebasalrate, tempBasal.rate)
|
||||
else holder.binding.rate.text = rh.gs(R.string.format_percent, tempBasal.rate.toInt())
|
||||
val now = dateUtil.now()
|
||||
var iob = IobTotal(now)
|
||||
val profile = profileFunction.getProfile(now)
|
||||
if (profile != null) iob = tempBasal.iobCalc(now, profile, activePlugin.activeInsulin)
|
||||
holder.binding.iob.text = rh.gs(R.string.formatinsulinunits, iob.basaliob)
|
||||
holder.binding.extendedFlag.visibility = (tempBasal.type == TemporaryBasal.Type.FAKE_EXTENDED).toVisibility()
|
||||
holder.binding.suspendFlag.visibility = (tempBasal.type == TemporaryBasal.Type.PUMP_SUSPEND).toVisibility()
|
||||
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
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 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
|
||||
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,
|
||||
ValueWithUnit.Timestamp(extendedBolus.timestamp),
|
||||
ValueWithUnit.Insulin(extendedBolus.amount),
|
||||
ValueWithUnit.UnitPerHour(extendedBolus.rate),
|
||||
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,
|
||||
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()))
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package info.nightscout.androidaps.activities.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.UserEntry
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.TreatmentsUserEntryFragmentBinding
|
||||
import info.nightscout.androidaps.databinding.TreatmentsUserEntryItemBinding
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.interfaces.ImportExportPrefs
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
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.Translator
|
||||
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
|
||||
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 java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TreatmentsUserEntryFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var translator: Translator
|
||||
@Inject lateinit var importExportPrefs: ImportExportPrefs
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var userEntryPresentationHelper: UserEntryPresentationHelper
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val millsToThePastFiltered = T.days(30).msecs()
|
||||
private val millsToThePastUnFiltered = T.days(3).msecs()
|
||||
|
||||
private var _binding: TreatmentsUserEntryFragmentBinding? = 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 =
|
||||
TreatmentsUserEntryFragmentBinding.inflate(inflater, container, false).also { _binding = it }.root
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.recyclerview.setHasFixedSize(true)
|
||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||
binding.ueExportToXml.setOnClickListener {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.ue_export_to_csv) + "?") {
|
||||
uel.log(Action.EXPORT_CSV, Sources.Treatments)
|
||||
importExportPrefs.exportUserEntriesCsv(activity)
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.showLoop.setOnCheckedChangeListener { _, _ ->
|
||||
rxBus.send(EventTreatmentUpdateGui())
|
||||
}
|
||||
}
|
||||
|
||||
fun swapAdapter() {
|
||||
val now = System.currentTimeMillis()
|
||||
if (binding.showLoop.isChecked)
|
||||
disposable.add( repository
|
||||
.getUserEntryDataFromTime(now - millsToThePastUnFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
else
|
||||
disposable.add( repository
|
||||
.getUserEntryFilteredDataFromTime(now - millsToThePastFiltered)
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe { list -> binding.recyclerview.swapAdapter(UserEntryAdapter(list), true) }
|
||||
)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
swapAdapter()
|
||||
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventPreferenceChange::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventTreatmentUpdateGui::class.java)
|
||||
.observeOn(aapsSchedulers.io)
|
||||
.debounce(1L, TimeUnit.SECONDS)
|
||||
.subscribe({ swapAdapter() }, fabricPrivacy::logException))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
inner class UserEntryAdapter internal constructor(var entries: List<UserEntry>) : RecyclerView.Adapter<UserEntryAdapter.UserEntryViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserEntryViewHolder {
|
||||
val view: View = LayoutInflater.from(parent.context).inflate(R.layout.treatments_user_entry_item, parent, false)
|
||||
return UserEntryViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: UserEntryViewHolder, position: Int) {
|
||||
val current = entries[position]
|
||||
holder.binding.date.text = dateUtil.dateAndTimeAndSecondsString(current.timestamp)
|
||||
holder.binding.action.text = userEntryPresentationHelper.actionToColoredString(current.action)
|
||||
holder.binding.s.text = current.note
|
||||
holder.binding.s.visibility = if (current.note != "") View.VISIBLE else View.GONE
|
||||
holder.binding.iconSource.setImageResource(userEntryPresentationHelper.iconId(current.source))
|
||||
holder.binding.iconSource.visibility = View.VISIBLE
|
||||
holder.binding.values.text = userEntryPresentationHelper.listToPresentationString(current.values)
|
||||
holder.binding.values.visibility = if (holder.binding.values.text != "") View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
inner class UserEntryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
val binding = TreatmentsUserEntryItemBinding.bind(itemView)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = entries.size
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package info.nightscout.androidaps.db
|
||||
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.*
|
||||
import info.nightscout.androidaps.events.*
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||
import io.reactivex.disposables.Disposable
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class CompatDBHelper @Inject constructor(
|
||||
val aapsLogger: AAPSLogger,
|
||||
val repository: AppRepository,
|
||||
val rxBus: RxBus
|
||||
) {
|
||||
|
||||
fun dbChangeDisposable(): Disposable = repository
|
||||
.changeObservable()
|
||||
.doOnSubscribe {
|
||||
rxBus.send(EventNewBG(null))
|
||||
}
|
||||
.subscribe {
|
||||
/**
|
||||
* GlucoseValues can come in batch
|
||||
* oldest one should be used for invalidation, newest one for for triggering Loop.
|
||||
* Thus we need to collect both
|
||||
*
|
||||
*/
|
||||
var newestGlucoseValue: GlucoseValue? = null
|
||||
it.filterIsInstance<GlucoseValue>().lastOrNull()?.let { gv ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg $gv")
|
||||
rxBus.send(EventNewBG(gv))
|
||||
newestGlucoseValue = gv
|
||||
}
|
||||
it.filterIsInstance<GlucoseValue>().map { gv -> gv.timestamp }.minOrNull()?.let { timestamp ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData $newestGlucoseValue")
|
||||
rxBus.send(EventNewHistoryData(timestamp, true, newestGlucoseValue))
|
||||
}
|
||||
it.filterIsInstance<Carbs>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange $timestamp")
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(timestamp, false))
|
||||
}
|
||||
it.filterIsInstance<Bolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTreatmentChange $timestamp")
|
||||
rxBus.send(EventTreatmentChange())
|
||||
rxBus.send(EventNewHistoryData(timestamp, false))
|
||||
}
|
||||
it.filterIsInstance<TemporaryBasal>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTempBasalChange $timestamp")
|
||||
rxBus.send(EventTempBasalChange())
|
||||
rxBus.send(EventNewHistoryData(timestamp, false))
|
||||
}
|
||||
it.filterIsInstance<ExtendedBolus>().map { t -> t.timestamp }.minOrNull()?.let { timestamp ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventExtendedBolusChange $timestamp")
|
||||
rxBus.send(EventExtendedBolusChange())
|
||||
rxBus.send(EventNewHistoryData(timestamp, false))
|
||||
}
|
||||
it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let { tt ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange $tt")
|
||||
rxBus.send(EventTempTargetChange())
|
||||
}
|
||||
it.filterIsInstance<TherapyEvent>().firstOrNull()?.let { te ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventTherapyEventChange $te")
|
||||
rxBus.send(EventTherapyEventChange())
|
||||
}
|
||||
it.filterIsInstance<Food>().firstOrNull()?.let { food ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventFoodDatabaseChanged $food")
|
||||
rxBus.send(EventFoodDatabaseChanged())
|
||||
}
|
||||
it.filterIsInstance<ProfileSwitch>().firstOrNull()?.let { ps ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventProfileSwitchChanged $ps")
|
||||
rxBus.send(EventProfileSwitchChanged())
|
||||
}
|
||||
it.filterIsInstance<EffectiveProfileSwitch>().firstOrNull()?.let { eps ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventEffectiveProfileSwitchChanged $eps")
|
||||
rxBus.send(EventEffectiveProfileSwitchChanged(eps))
|
||||
}
|
||||
it.filterIsInstance<OfflineEvent>().firstOrNull()?.let { oe ->
|
||||
aapsLogger.debug(LTag.DATABASE, "Firing EventOfflineChange $oe")
|
||||
rxBus.send(EventOfflineChange())
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,115 +0,0 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import com.j256.ormlite.dao.CloseableIterator;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
|
||||
|
||||
@Singleton
|
||||
public class DatabaseHelperProvider implements DatabaseHelperInterface {
|
||||
|
||||
@Inject DatabaseHelperProvider() {
|
||||
}
|
||||
|
||||
@NotNull @Override public List<BgReading> getAllBgreadingsDataFromTime(long mills, boolean ascending) {
|
||||
return MainApp.getDbHelper().getAllBgreadingsDataFromTime(mills, ascending);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NotNull CareportalEvent careportalEvent) {
|
||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NotNull DanaRHistoryRecord record) {
|
||||
MainApp.getDbHelper().createOrUpdate(record);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NotNull OmnipodHistoryRecord record) {
|
||||
MainApp.getDbHelper().createOrUpdate(record);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<DanaRHistoryRecord> getDanaRHistoryRecordsByType(byte type) {
|
||||
return MainApp.getDbHelper().getDanaRHistoryRecordsByType(type);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<TDD> getTDDs() {
|
||||
return MainApp.getDbHelper().getTDDs();
|
||||
}
|
||||
|
||||
@Override public long size(@NotNull String table) {
|
||||
return MainApp.getDbHelper().size(table);
|
||||
}
|
||||
|
||||
@Override public void create(@NotNull DbRequest record) {
|
||||
try {
|
||||
MainApp.getDbHelper().create(record);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void deleteAllDbRequests() {
|
||||
MainApp.getDbHelper().deleteAllDbRequests();
|
||||
}
|
||||
|
||||
@Override public int deleteDbRequest(@NotNull String id) {
|
||||
return MainApp.getDbHelper().deleteDbRequest(id);
|
||||
}
|
||||
|
||||
@Override public void deleteDbRequestbyMongoId(@NotNull String action, @NotNull String _id) {
|
||||
MainApp.getDbHelper().deleteDbRequestbyMongoId(action, _id);
|
||||
}
|
||||
|
||||
@NotNull @Override public CloseableIterator<DbRequest> getDbRequestInterator() {
|
||||
return MainApp.getDbHelper().getDbRequestInterator();
|
||||
}
|
||||
|
||||
@Override public long roundDateToSec(long date) {
|
||||
return MainApp.getDbHelper().roundDateToSec(date);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdateTDD(@NotNull TDD record) {
|
||||
MainApp.getDbHelper().createOrUpdateTDD(record);
|
||||
}
|
||||
|
||||
@Override public void createOrUpdate(@NotNull TemporaryBasal tempBasal) {
|
||||
MainApp.getDbHelper().createOrUpdate(tempBasal);
|
||||
}
|
||||
|
||||
@NotNull @Override public TemporaryBasal findTempBasalByPumpId(long id) {
|
||||
return MainApp.getDbHelper().findTempBasalByPumpId(id);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<TemporaryBasal> getTemporaryBasalsDataFromTime(long mills, boolean ascending) {
|
||||
return MainApp.getDbHelper().getTemporaryBasalsDataFromTime(mills, ascending);
|
||||
}
|
||||
|
||||
@Override public CareportalEvent getCareportalEventFromTimestamp(long timestamp) {
|
||||
return MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<OmnipodHistoryRecord> getAllOmnipodHistoryRecordsFromTimestamp(long timestamp, boolean ascending) {
|
||||
return MainApp.getDbHelper().getAllOmnipodHistoryRecordsFromTimeStamp(timestamp, ascending);
|
||||
}
|
||||
|
||||
@Nullable @Override public OmnipodHistoryRecord findOmnipodHistoryRecordByPumpId(long pumpId) {
|
||||
return MainApp.getDbHelper().findOmnipodHistoryRecordByPumpId(pumpId);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<TDD> getTDDsForLastXDays(int days) {
|
||||
return MainApp.getDbHelper().getTDDsForLastXDays(days);
|
||||
}
|
||||
|
||||
@NotNull @Override public List<ProfileSwitch> getProfileSwitchData(long from, boolean ascending) {
|
||||
return MainApp.getDbHelper().getProfileSwitchData(from, ascending);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package info.nightscout.androidaps.db
|
||||
|
||||
import com.j256.ormlite.field.DatabaseField
|
||||
import com.j256.ormlite.table.DatabaseTable
|
||||
|
||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_OPEN_HUMANS_QUEUE)
|
||||
data class OHQueueItem @JvmOverloads constructor(
|
||||
@DatabaseField(generatedId = true)
|
||||
val id: Long = 0,
|
||||
@DatabaseField
|
||||
val file: String = "",
|
||||
@DatabaseField
|
||||
val content: String = ""
|
||||
)
|
|
@ -1,44 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.MainActivity
|
||||
import info.nightscout.androidaps.activities.*
|
||||
import info.nightscout.androidaps.historyBrowser.HistoryBrowseActivity
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
|
||||
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
|
||||
import info.nightscout.androidaps.plugins.pump.common.dialog.RileyLinkBLEConfigActivity
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity
|
||||
import info.nightscout.androidaps.plugins.pump.insight.activities.InsightAlertActivity
|
||||
import info.nightscout.androidaps.plugins.pump.insight.activities.InsightPairingActivity
|
||||
import info.nightscout.androidaps.plugins.pump.insight.activities.InsightPairingInformationActivity
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.MedtronicHistoryActivity
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ActivitiesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesHistoryBrowseActivity(): HistoryBrowseActivity
|
||||
@ContributesAndroidInjector abstract fun contributesInsightAlertActivity(): InsightAlertActivity
|
||||
@ContributesAndroidInjector abstract fun contributesInsightPairingActivity(): InsightPairingActivity
|
||||
@ContributesAndroidInjector abstract fun contributesInsightPairingInformationActivity(): InsightPairingInformationActivity
|
||||
@ContributesAndroidInjector abstract fun contributesLogSettingActivity(): LogSettingActivity
|
||||
@ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity
|
||||
@ContributesAndroidInjector abstract fun contributesMedtronicHistoryActivity(): MedtronicHistoryActivity
|
||||
@ContributesAndroidInjector abstract fun contributesPreferencesActivity(): PreferencesActivity
|
||||
@ContributesAndroidInjector abstract fun contributesQuickWizardListActivity(): QuickWizardListActivity
|
||||
@ContributesAndroidInjector abstract fun contributesRequestDexcomPermissionActivity(): RequestDexcomPermissionActivity
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkStatusActivity(): RileyLinkStatusActivity
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkBLEConfigActivity(): RileyLinkBLEConfigActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSetupWizardActivity(): SetupWizardActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSingleFragmentActivity(): SingleFragmentActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity
|
||||
@ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
|
||||
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity
|
||||
@ContributesAndroidInjector abstract fun contributesOpenHumansLoginActivity(): OpenHumansLoginActivity
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import dagger.android.AndroidInjectionModule
|
||||
import dagger.android.AndroidInjector
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.core.di.CoreModule
|
||||
import info.nightscout.androidaps.dana.di.DanaModule
|
||||
import info.nightscout.androidaps.danar.di.DanaRModule
|
||||
import info.nightscout.androidaps.danars.di.DanaRSModule
|
||||
import info.nightscout.androidaps.plugins.pump.common.dagger.RileyLinkModule
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dagger.OmnipodModule
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Component(
|
||||
modules = [
|
||||
AndroidInjectionModule::class,
|
||||
PluginsModule::class,
|
||||
SkinsModule::class,
|
||||
ActivitiesModule::class,
|
||||
FragmentsModule::class,
|
||||
AppModule::class,
|
||||
ReceiversModule::class,
|
||||
ServicesModule::class,
|
||||
AutomationModule::class,
|
||||
CommandQueueModule::class,
|
||||
ObjectivesModule::class,
|
||||
WizardModule::class,
|
||||
RileyLinkModule::class,
|
||||
MedtronicModule::class,
|
||||
OmnipodModule::class,
|
||||
APSModule::class,
|
||||
PreferencesModule::class,
|
||||
OverviewModule::class,
|
||||
DataClassesModule::class,
|
||||
SMSModule::class,
|
||||
UIModule::class,
|
||||
CoreModule::class,
|
||||
DanaModule::class,
|
||||
DanaRModule::class,
|
||||
DanaRSModule::class,
|
||||
OHUploaderModule::class
|
||||
]
|
||||
)
|
||||
interface AppComponent : AndroidInjector<MainApp> {
|
||||
|
||||
@Component.Builder
|
||||
interface Builder {
|
||||
|
||||
@BindsInstance
|
||||
fun application(mainApp: MainApp): Builder
|
||||
|
||||
fun build(): AppComponent
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Binds
|
||||
import dagger.Lazy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.db.DatabaseHelperProvider
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefs
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.queue.CommandQueue
|
||||
import info.nightscout.androidaps.utils.androidNotification.NotificationHolder
|
||||
import info.nightscout.androidaps.utils.storage.FileStorage
|
||||
import info.nightscout.androidaps.utils.storage.Storage
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module(includes = [
|
||||
AppModule.AppBindings::class
|
||||
])
|
||||
open class AppModule {
|
||||
|
||||
@Provides
|
||||
fun providesPlugins(configInterface: ConfigInterface,
|
||||
@PluginsModule.AllConfigs allConfigs: Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>,
|
||||
@PluginsModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>)
|
||||
: List<@JvmSuppressWildcards PluginBase> {
|
||||
val plugins = allConfigs.toMutableMap()
|
||||
if (configInterface.PUMPDRIVERS) plugins += pumpDrivers.get()
|
||||
if (configInterface.APS) plugins += aps.get()
|
||||
if (!configInterface.NSCLIENT) plugins += notNsClient.get()
|
||||
return plugins.toList().sortedBy { it.first }.map { it.second }
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStorage(): Storage {
|
||||
return FileStorage()
|
||||
}
|
||||
|
||||
@Module
|
||||
interface AppBindings {
|
||||
|
||||
@Binds fun bindContext(mainApp: MainApp): Context
|
||||
@Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector
|
||||
@Binds fun bindActivePluginProvider(pluginStore: PluginStore): ActivePluginProvider
|
||||
@Binds fun bindCommandQueueProvider(commandQueue: CommandQueue): CommandQueueProvider
|
||||
@Binds fun bindConfigInterface(config: Config): ConfigInterface
|
||||
@Binds fun bindConfigBuilderInterface(configBuilderPlugin: ConfigBuilderPlugin): ConfigBuilderInterface
|
||||
@Binds fun bindTreatmentInterface(treatmentsPlugin: TreatmentsPlugin): TreatmentsInterface
|
||||
@Binds fun bindDatabaseHelperInterface(databaseHelperProvider: DatabaseHelperProvider): DatabaseHelperInterface
|
||||
@Binds fun bindUploadQueueInterface(uploadQueue: UploadQueue): UploadQueueInterface
|
||||
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolder): NotificationHolderInterface
|
||||
@Binds fun bindImportExportPrefsInterface(importExportPrefs: ImportExportPrefs): ImportExportPrefsInterface
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.*
|
||||
import info.nightscout.androidaps.queue.CommandQueue
|
||||
import info.nightscout.androidaps.queue.commands.*
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class AutomationModule {
|
||||
@ContributesAndroidInjector abstract fun automationEventInjector(): AutomationEvent
|
||||
|
||||
@ContributesAndroidInjector abstract fun triggerInjector(): Trigger
|
||||
@ContributesAndroidInjector abstract fun triggerAutosensValueInjector(): TriggerAutosensValue
|
||||
@ContributesAndroidInjector abstract fun triggerBgInjector(): TriggerBg
|
||||
@ContributesAndroidInjector abstract fun triggerBolusAgoInjector(): TriggerBolusAgo
|
||||
@ContributesAndroidInjector abstract fun triggerCOBInjector(): TriggerCOB
|
||||
@ContributesAndroidInjector abstract fun triggerConnectorInjector(): TriggerConnector
|
||||
@ContributesAndroidInjector abstract fun triggerDeltaInjector(): TriggerDelta
|
||||
@ContributesAndroidInjector abstract fun triggerDummyInjector(): TriggerDummy
|
||||
@ContributesAndroidInjector abstract fun triggerIobInjector(): TriggerIob
|
||||
@ContributesAndroidInjector abstract fun triggerLocationInjector(): TriggerLocation
|
||||
@ContributesAndroidInjector abstract fun triggerProfilePercentInjector(): TriggerProfilePercent
|
||||
@ContributesAndroidInjector abstract fun triggerPumpLastConnectionInjector(): TriggerPumpLastConnection
|
||||
@ContributesAndroidInjector abstract fun triggerBTDeviceInjector(): TriggerBTDevice
|
||||
@ContributesAndroidInjector abstract fun triggerRecurringTimeInjector(): TriggerRecurringTime
|
||||
@ContributesAndroidInjector abstract fun triggerTempTargetInjector(): TriggerTempTarget
|
||||
@ContributesAndroidInjector abstract fun triggerTime(): TriggerTime
|
||||
@ContributesAndroidInjector abstract fun triggerTimeRangeInjector(): TriggerTimeRange
|
||||
@ContributesAndroidInjector abstract fun triggerWifiSsidInjector(): TriggerWifiSsid
|
||||
|
||||
@ContributesAndroidInjector abstract fun actionInjector(): Action
|
||||
@ContributesAndroidInjector abstract fun actionLoopDisableInjector(): ActionLoopDisable
|
||||
@ContributesAndroidInjector abstract fun actionLoopEnableInjector(): ActionLoopEnable
|
||||
@ContributesAndroidInjector abstract fun actionLoopResumeInjector(): ActionLoopResume
|
||||
@ContributesAndroidInjector abstract fun actionLoopSuspendInjector(): ActionLoopSuspend
|
||||
@ContributesAndroidInjector abstract fun actionNotificationInjector(): ActionNotification
|
||||
@ContributesAndroidInjector abstract fun actionAlarmInjector(): ActionAlarm
|
||||
@ContributesAndroidInjector abstract fun actionProfileSwitchInjector(): ActionProfileSwitch
|
||||
@ContributesAndroidInjector abstract fun actionProfileSwitchPercentInjector(): ActionProfileSwitchPercent
|
||||
@ContributesAndroidInjector abstract fun actionSendSMSInjector(): ActionSendSMS
|
||||
@ContributesAndroidInjector abstract fun actionStartTempTargetInjector(): ActionStartTempTarget
|
||||
@ContributesAndroidInjector abstract fun actionStopTempTargetInjector(): ActionStopTempTarget
|
||||
@ContributesAndroidInjector abstract fun actionDummyInjector(): ActionDummy
|
||||
|
||||
@ContributesAndroidInjector abstract fun elementInjector(): Element
|
||||
@ContributesAndroidInjector abstract fun inputBgInjector(): InputBg
|
||||
@ContributesAndroidInjector abstract fun inputButtonInjector(): InputButton
|
||||
@ContributesAndroidInjector abstract fun comparatorInjector(): Comparator
|
||||
@ContributesAndroidInjector abstract fun comparatorConnectInjector(): ComparatorConnect
|
||||
@ContributesAndroidInjector abstract fun comparatorExistsInjector(): ComparatorExists
|
||||
@ContributesAndroidInjector abstract fun inputDateTimeInjector(): InputDateTime
|
||||
@ContributesAndroidInjector abstract fun inputDeltaInjector(): InputDelta
|
||||
@ContributesAndroidInjector abstract fun inputDoubleInjector(): InputDouble
|
||||
@ContributesAndroidInjector abstract fun inputDropdownMenuInjector(): InputDropdownMenu
|
||||
@ContributesAndroidInjector abstract fun inputDurationInjector(): InputDuration
|
||||
@ContributesAndroidInjector abstract fun inputInsulinInjector(): InputInsulin
|
||||
@ContributesAndroidInjector abstract fun inputLocationModeInjector(): InputLocationMode
|
||||
@ContributesAndroidInjector abstract fun inputPercentInjector(): InputPercent
|
||||
@ContributesAndroidInjector abstract fun inputProfileNameInjector(): InputProfileName
|
||||
@ContributesAndroidInjector abstract fun inputStringInjector(): InputString
|
||||
@ContributesAndroidInjector abstract fun inputTempTargetInjector(): InputTempTarget
|
||||
@ContributesAndroidInjector abstract fun inputTimeRangeInjector(): InputTimeRange
|
||||
@ContributesAndroidInjector abstract fun inputTimeInjector(): InputTime
|
||||
@ContributesAndroidInjector abstract fun inputWeekDayInjector(): InputWeekDay
|
||||
@ContributesAndroidInjector abstract fun labelWithElementInjector(): LabelWithElement
|
||||
@ContributesAndroidInjector abstract fun staticLabelInjector(): StaticLabel
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.db.*
|
||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodService
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentService
|
||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class DataClassesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun glucoseStatusInjector(): GlucoseStatus
|
||||
|
||||
@ContributesAndroidInjector abstract fun DatabaseHelperInjector(): DatabaseHelper
|
||||
@ContributesAndroidInjector abstract fun treatmentServiceInjector(): TreatmentService
|
||||
@ContributesAndroidInjector abstract fun foodServiceInjector(): FoodService
|
||||
|
||||
@ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard
|
||||
@ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.activities.MyPreferenceFragment
|
||||
import info.nightscout.androidaps.dialogs.*
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopFragment
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAFragment
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBFragment
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderFragment
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
||||
import info.nightscout.androidaps.plugins.general.actions.ActionsFragment
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationFragment
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseActionDialog
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTriggerDialog
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditActionDialog
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditTriggerDialog
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodFragment
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansFragment
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
|
||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboFragment
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusGeneralFragment
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusHistoryFragment
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightFragment
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicFragment
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.dialog.RileyLinkStatusDeviceMedtronic
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.ui.OmnipodOverviewFragment
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsFragment
|
||||
import info.nightscout.androidaps.plugins.treatments.fragments.*
|
||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class FragmentsModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPreferencesFragment(): MyPreferenceFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment
|
||||
@ContributesAndroidInjector abstract fun contributesAutomationFragment(): AutomationFragment
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesComboFragment(): ComboFragment
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesFoodFragment(): FoodFragment
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): LocalProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOpenAPSAMAFragment(): OpenAPSAMAFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOpenAPSSMBFragment(): OpenAPSSMBFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLocalInsightFragment(): LocalInsightFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMedtronicFragment(): MedtronicFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOmnipodFragment(): OmnipodOverviewFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileFragment(): NSProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsFragment(): TreatmentsFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsExtendedBolusesFragment(): TreatmentsExtendedBolusesFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsCareportalFragment(): TreatmentsCareportalFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesTreatmentsProfileSwitchFragment(): TreatmentsProfileSwitchFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesOpenHumansFragment(): OpenHumansFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog
|
||||
@ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog
|
||||
@ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditActionDialog(): EditActionDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditEventDialog(): EditEventDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditTriggerDialog(): EditTriggerDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesExtendedBolusDialog(): ExtendedBolusDialog
|
||||
@ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog
|
||||
@ContributesAndroidInjector abstract fun contributesChooseActionDialog(): ChooseActionDialog
|
||||
@ContributesAndroidInjector abstract fun contributesChooseTriggerDialog(): ChooseTriggerDialog
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinDialog(): InsulinDialog
|
||||
@ContributesAndroidInjector abstract fun contributesLoopDialog(): LoopDialog
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): ObjectivesExamDialog
|
||||
@ContributesAndroidInjector abstract fun contributesProfileSwitchDialog(): ProfileSwitchDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTempBasalDialog(): TempBasalDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTempTargetDialog(): TempTargetDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentDialog(): TreatmentDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesExchangeAuthTokenDialot(): OpenHumansLoginActivity.ExchangeAuthTokenDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesRileyLinkStatusGeneral(): RileyLinkStatusGeneralFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesRileyLinkStatusHistoryFragment(): RileyLinkStatusHistoryFragment
|
||||
@ContributesAndroidInjector
|
||||
abstract fun contributesRileyLinkStatusDeviceMedtronic(): RileyLinkStatusDeviceMedtronic
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.MedtronicCommunicationManager
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.comm.ui.MedtronicUITask
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class MedtronicModule {
|
||||
@ContributesAndroidInjector abstract fun medtronicCommunicationManagerProvider(): MedtronicCommunicationManager
|
||||
@ContributesAndroidInjector abstract fun medtronicUITaskProvider(): MedtronicUITask
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OHUploadWorker
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class OHUploaderModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesOHUploadWorkerInjector(): OHUploadWorker
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.ClassicPrefsFormat
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat
|
||||
import info.nightscout.androidaps.utils.CryptoUtil
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class PreferencesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun cryptoUtilInjector(): CryptoUtil
|
||||
@ContributesAndroidInjector abstract fun encryptedPrefsFormatInjector(): EncryptedPrefsFormat
|
||||
@ContributesAndroidInjector abstract fun classicPrefsFormatInjector(): ClassicPrefsFormat
|
||||
@ContributesAndroidInjector abstract fun prefImportListProviderInjector(): PrefFileListProvider
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.DismissNotificationService
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.DummyService
|
||||
import info.nightscout.androidaps.plugins.general.wear.wearintegration.WatchUpdaterService
|
||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkService
|
||||
import info.nightscout.androidaps.plugins.pump.insight.InsightAlertService
|
||||
import info.nightscout.androidaps.plugins.pump.insight.connection_service.InsightConnectionService
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.service.RileyLinkMedtronicService
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.service.RileyLinkOmnipodService
|
||||
import info.nightscout.androidaps.services.AlarmSoundService
|
||||
import info.nightscout.androidaps.services.DataService
|
||||
import info.nightscout.androidaps.services.LocationService
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ServicesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
|
||||
@ContributesAndroidInjector abstract fun contributesDataService(): DataService
|
||||
@ContributesAndroidInjector abstract fun contributesDismissNotificationService(): DismissNotificationService
|
||||
@ContributesAndroidInjector abstract fun contributesDummyService(): DummyService
|
||||
@ContributesAndroidInjector abstract fun contributesLocationService(): LocationService
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientService(): NSClientService
|
||||
@ContributesAndroidInjector abstract fun contributesWatchUpdaterService(): WatchUpdaterService
|
||||
@ContributesAndroidInjector abstract fun contributesInsightAlertService(): InsightAlertService
|
||||
@ContributesAndroidInjector abstract fun contributesInsightConnectionService(): InsightConnectionService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkService(): RileyLinkService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkMedtronicService(): RileyLinkMedtronicService
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkOmnipodService(): RileyLinkOmnipodService
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.DetermineBasalAdapterAMAJS
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.DetermineBasalResultAMA
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalAdapterSMBJS
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.MainActivity
|
||||
import info.nightscout.androidaps.activities.*
|
||||
import info.nightscout.androidaps.activities.HistoryBrowseActivity
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
|
||||
import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity
|
||||
import info.nightscout.androidaps.setupwizard.SetupWizardActivity
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ActivitiesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsActivity(): TreatmentsActivity
|
||||
@ContributesAndroidInjector abstract fun contributesHistoryBrowseActivity(): HistoryBrowseActivity
|
||||
@ContributesAndroidInjector abstract fun contributesLogSettingActivity(): LogSettingActivity
|
||||
@ContributesAndroidInjector abstract fun contributeMainActivity(): MainActivity
|
||||
@ContributesAndroidInjector abstract fun contributesPreferencesActivity(): PreferencesActivity
|
||||
@ContributesAndroidInjector abstract fun contributesQuickWizardListActivity(): QuickWizardListActivity
|
||||
@ContributesAndroidInjector abstract fun contributesRequestDexcomPermissionActivity(): RequestDexcomPermissionActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSetupWizardActivity(): SetupWizardActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSingleFragmentActivity(): SingleFragmentActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorOtpActivity(): SmsCommunicatorOtpActivity
|
||||
@ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity
|
||||
@ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity
|
||||
@ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import dagger.android.AndroidInjectionModule
|
||||
import dagger.android.AndroidInjector
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.automation.di.AutomationModule
|
||||
import info.nightscout.androidaps.combo.di.ComboModule
|
||||
import info.nightscout.androidaps.dana.di.DanaHistoryModule
|
||||
import info.nightscout.androidaps.dana.di.DanaModule
|
||||
import info.nightscout.androidaps.danar.di.DanaRModule
|
||||
import info.nightscout.androidaps.danars.di.DanaRSModule
|
||||
import info.nightscout.androidaps.database.DatabaseModule
|
||||
import info.nightscout.androidaps.diaconn.di.DiaconnG8Module
|
||||
import info.nightscout.androidaps.insight.di.InsightDatabaseModule
|
||||
import info.nightscout.androidaps.insight.di.InsightModule
|
||||
import info.nightscout.androidaps.plugin.general.openhumans.dagger.OpenHumansModule
|
||||
import info.nightscout.androidaps.plugins.pump.common.di.PumpCommonModule
|
||||
import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.dagger.OmnipodDashModule
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.dagger.OmnipodErosModule
|
||||
import info.nightscout.shared.di.SharedModule
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
@Component(
|
||||
modules = [
|
||||
AndroidInjectionModule::class,
|
||||
DatabaseModule::class,
|
||||
PluginsModule::class,
|
||||
SkinsModule::class,
|
||||
ActivitiesModule::class,
|
||||
FragmentsModule::class,
|
||||
AppModule::class,
|
||||
ReceiversModule::class,
|
||||
ServicesModule::class,
|
||||
AutomationModule::class,
|
||||
CommandQueueModule::class,
|
||||
ObjectivesModule::class,
|
||||
WizardModule::class,
|
||||
PumpCommonModule::class,
|
||||
RileyLinkModule::class,
|
||||
MedtronicModule::class,
|
||||
OmnipodDashModule::class,
|
||||
OmnipodErosModule::class,
|
||||
APSModule::class,
|
||||
PreferencesModule::class,
|
||||
OverviewModule::class,
|
||||
DataClassesModule::class,
|
||||
SMSModule::class,
|
||||
UIModule::class,
|
||||
CoreModule::class,
|
||||
DanaModule::class,
|
||||
DanaHistoryModule::class,
|
||||
DanaRModule::class,
|
||||
DanaRSModule::class,
|
||||
ComboModule::class,
|
||||
InsightModule::class,
|
||||
InsightDatabaseModule::class,
|
||||
WorkersModule::class,
|
||||
DiaconnG8Module::class,
|
||||
OpenHumansModule::class,
|
||||
SharedModule::class
|
||||
]
|
||||
)
|
||||
interface AppComponent : AndroidInjector<MainApp> {
|
||||
|
||||
@Component.Builder
|
||||
interface Builder {
|
||||
|
||||
@BindsInstance
|
||||
fun application(mainApp: MainApp): Builder
|
||||
|
||||
fun build(): AppComponent
|
||||
}
|
||||
}
|
108
app/src/main/java/info/nightscout/androidaps/di/AppModule.kt
Normal file
108
app/src/main/java/info/nightscout/androidaps/di/AppModule.kt
Normal file
|
@ -0,0 +1,108 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Binds
|
||||
import dagger.Lazy
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.PluginStore
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.DataSyncSelectorImplementation
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
|
||||
import info.nightscout.androidaps.queue.CommandQueueImplementation
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
|
||||
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
|
||||
import info.nightscout.androidaps.utils.resources.IconsProviderImplementation
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers
|
||||
import info.nightscout.androidaps.utils.storage.FileStorage
|
||||
import info.nightscout.androidaps.utils.storage.Storage
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("unused")
|
||||
@Module(includes = [
|
||||
AppModule.AppBindings::class
|
||||
])
|
||||
open class AppModule {
|
||||
|
||||
@Provides
|
||||
fun providesPlugins(config: Config,
|
||||
@PluginsModule.AllConfigs allConfigs: Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>,
|
||||
@PluginsModule.PumpDriver pumpDrivers: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsModule.NotNSClient notNsClient: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>,
|
||||
@PluginsModule.APS aps: Lazy<Map<@JvmSuppressWildcards Int, @JvmSuppressWildcards PluginBase>>)
|
||||
: List<@JvmSuppressWildcards PluginBase> {
|
||||
val plugins = allConfigs.toMutableMap()
|
||||
if (config.PUMPDRIVERS) plugins += pumpDrivers.get()
|
||||
if (config.APS) plugins += aps.get()
|
||||
if (!config.NSCLIENT) plugins += notNsClient.get()
|
||||
return plugins.toList().sortedBy { it.first }.map { it.second }
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideStorage(): Storage = FileStorage()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideBuildHelper(config: Config, fileListProvider: PrefFileListProvider): BuildHelper = BuildHelperImpl(config, fileListProvider)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
internal fun provideSchedulers(): AapsSchedulers = DefaultAapsSchedulers()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideProfileFunction(
|
||||
aapsLogger: AAPSLogger, sp: SP, rxBus: RxBus, rh:
|
||||
ResourceHelper, activePlugin:
|
||||
ActivePlugin, repository: AppRepository, dateUtil: DateUtil, config: Config, hardLimits: HardLimits,
|
||||
aapsSchedulers: AapsSchedulers, fabricPrivacy: FabricPrivacy, deviceStatusData: DeviceStatusData
|
||||
): ProfileFunction =
|
||||
ProfileFunctionImplementation(
|
||||
aapsLogger, sp, rxBus, rh, activePlugin, repository, dateUtil,
|
||||
config, hardLimits, aapsSchedulers, fabricPrivacy, deviceStatusData
|
||||
)
|
||||
|
||||
@Module
|
||||
interface AppBindings {
|
||||
|
||||
@Binds fun bindContext(mainApp: MainApp): Context
|
||||
@Binds fun bindInjector(mainApp: MainApp): HasAndroidInjector
|
||||
@Binds fun bindActivePlugin(pluginStore: PluginStore): ActivePlugin
|
||||
@Binds fun bindCommandQueue(commandQueue: CommandQueueImplementation): CommandQueue
|
||||
@Binds fun bindConfigInterface(config: ConfigImpl): Config
|
||||
|
||||
@Binds fun bindConfigBuilderInterface(configBuilderPlugin: ConfigBuilderPlugin): ConfigBuilder
|
||||
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolderImpl): NotificationHolder
|
||||
@Binds fun bindImportExportPrefsInterface(importExportPrefs: ImportExportPrefsImpl): ImportExportPrefs
|
||||
@Binds fun bindIconsProviderInterface(iconsProvider: IconsProviderImplementation): IconsProvider
|
||||
@Binds fun bindLoopInterface(loopPlugin: LoopPlugin): Loop
|
||||
@Binds fun bindIobCobCalculatorInterface(iobCobCalculatorPlugin: IobCobCalculatorPlugin): IobCobCalculator
|
||||
@Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator
|
||||
@Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
|
||||
|
||||
@Binds fun bindPumpSync(pumpSyncImplementation: PumpSyncImplementation): PumpSync
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1,15 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.queue.CommandQueue
|
||||
import info.nightscout.androidaps.queue.CommandQueueImplementation
|
||||
import info.nightscout.androidaps.queue.commands.*
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class CommandQueueModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun commandQueueInjector(): CommandQueue
|
||||
@ContributesAndroidInjector abstract fun commandQueueInjector(): CommandQueueImplementation
|
||||
@ContributesAndroidInjector abstract fun commandBolusInjector(): CommandBolus
|
||||
@ContributesAndroidInjector abstract fun commandCancelExtendedBolusInjector(): CommandCancelExtendedBolus
|
||||
@ContributesAndroidInjector abstract fun commandCancelTempBasalInjector(): CommandCancelTempBasal
|
|
@ -0,0 +1,17 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class DataClassesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun glucoseStatusInjector(): GlucoseStatus
|
||||
|
||||
@ContributesAndroidInjector abstract fun bolusWizardInjector(): BolusWizard
|
||||
@ContributesAndroidInjector abstract fun quickWizardEntryInjector(): QuickWizardEntry
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.activities.MyPreferenceFragment
|
||||
import info.nightscout.androidaps.dialogs.*
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopFragment
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAFragment
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBFragment
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderFragment
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.activities.ObjectivesExamDialog
|
||||
import info.nightscout.androidaps.plugins.general.actions.ActionsFragment
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationFragment
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodFragment
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment
|
||||
import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment
|
||||
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolFragment
|
||||
import info.nightscout.androidaps.plugins.general.wear.WearFragment
|
||||
import info.nightscout.androidaps.plugins.insulin.InsulinFragment
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpFragment
|
||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment
|
||||
import info.nightscout.androidaps.activities.fragments.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.*
|
||||
import info.nightscout.androidaps.utils.protection.PasswordCheck
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class FragmentsModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPreferencesFragment(): MyPreferenceFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesActionsFragment(): ActionsFragment
|
||||
@ContributesAndroidInjector abstract fun contributesAutomationFragment(): AutomationFragment
|
||||
@ContributesAndroidInjector abstract fun contributesBGSourceFragment(): BGSourceFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesConfigBuilderFragment(): ConfigBuilderFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesFoodFragment(): FoodFragment
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinFragment(): InsulinFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLocalProfileFragment(): LocalProfileFragment
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesFragment(): ObjectivesFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOpenAPSAMAFragment(): OpenAPSAMAFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOpenAPSSMBFragment(): OpenAPSSMBFragment
|
||||
@ContributesAndroidInjector abstract fun contributesOverviewFragment(): OverviewFragment
|
||||
@ContributesAndroidInjector abstract fun contributesLoopFragment(): LoopFragment
|
||||
@ContributesAndroidInjector abstract fun contributesMaintenanceFragment(): MaintenanceFragment
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientFragment(): NSClientFragment
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorFragment(): SmsCommunicatorFragment
|
||||
@ContributesAndroidInjector abstract fun contributesWearFragment(): WearFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesTidepoolFragment(): TidepoolFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsBolusFragment(): TreatmentsBolusCarbsFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsTemporaryBasalsFragment(): TreatmentsTemporaryBasalsFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsTempTargetFragment(): TreatmentsTempTargetFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsExtendedBolusesFragment(): TreatmentsExtendedBolusesFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsCareportalFragment(): TreatmentsCareportalFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsProfileSwitchFragment(): TreatmentsProfileSwitchFragment
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentsUserEntryFragment(): TreatmentsUserEntryFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog
|
||||
@ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog
|
||||
@ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditActionDialog(): EditActionDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditEventDialog(): EditEventDialog
|
||||
@ContributesAndroidInjector abstract fun contributesEditTriggerDialog(): EditTriggerDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesEditQuickWizardDialog(): EditQuickWizardDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesExtendedBolusDialog(): ExtendedBolusDialog
|
||||
@ContributesAndroidInjector abstract fun contributesFillDialog(): FillDialog
|
||||
@ContributesAndroidInjector abstract fun contributesChooseActionDialog(): ChooseActionDialog
|
||||
@ContributesAndroidInjector abstract fun contributesChooseTriggerDialog(): ChooseTriggerDialog
|
||||
@ContributesAndroidInjector abstract fun contributesChooseOperationDialog(): ChooseOperationDialog
|
||||
@ContributesAndroidInjector abstract fun contributesInsulinDialog(): InsulinDialog
|
||||
@ContributesAndroidInjector abstract fun contributesLoopDialog(): LoopDialog
|
||||
@ContributesAndroidInjector abstract fun contributesObjectivesExamDialog(): ObjectivesExamDialog
|
||||
@ContributesAndroidInjector abstract fun contributesProfileSwitchDialog(): ProfileSwitchDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTempBasalDialog(): TempBasalDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTempTargetDialog(): TempTargetDialog
|
||||
@ContributesAndroidInjector abstract fun contributesTreatmentDialog(): TreatmentDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog
|
||||
@ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
|
@ -17,7 +17,6 @@ abstract class ObjectivesModule {
|
|||
@ContributesAndroidInjector abstract fun objective5Injector(): Objective5
|
||||
@ContributesAndroidInjector abstract fun objective6Injector(): Objective6
|
||||
@ContributesAndroidInjector abstract fun objective7Injector(): Objective7
|
||||
@ContributesAndroidInjector abstract fun objective8Injector(): Objective8
|
||||
@ContributesAndroidInjector abstract fun objective9Injector(): Objective9
|
||||
@ContributesAndroidInjector abstract fun objective10Injector(): Objective10
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
@ -8,11 +8,14 @@ import info.nightscout.androidaps.danaRKorean.DanaRKoreanPlugin
|
|||
import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||
import info.nightscout.androidaps.danar.DanaRPlugin
|
||||
import info.nightscout.androidaps.danars.DanaRSPlugin
|
||||
import info.nightscout.androidaps.diaconn.DiaconnG8Plugin
|
||||
import info.nightscout.androidaps.interfaces.PluginBase
|
||||
import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin
|
||||
|
@ -25,7 +28,6 @@ import info.nightscout.androidaps.plugins.general.dataBroadcaster.DataBroadcastP
|
|||
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin
|
||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
|
@ -37,20 +39,20 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin
|
|||
import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.mdi.MDIPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.medtronic.MedtronicPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||
import info.nightscout.androidaps.plugins.source.*
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import javax.inject.Qualifier
|
||||
|
||||
@Suppress("unused")
|
||||
@Module
|
||||
abstract class PluginsModule {
|
||||
|
||||
|
@ -58,6 +60,12 @@ abstract class PluginsModule {
|
|||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(0)
|
||||
abstract fun bindPersistentNotificationPlugin(plugin: PersistentNotificationPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(5)
|
||||
abstract fun bindOverviewPlugin(plugin: OverviewPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
|
@ -150,6 +158,18 @@ abstract class PluginsModule {
|
|||
@IntKey(140)
|
||||
abstract fun bindComboPlugin(plugin: ComboPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@PumpDriver
|
||||
@IntoMap
|
||||
@IntKey(145)
|
||||
abstract fun bindOmnipodErosPumpPlugin(plugin: OmnipodErosPumpPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@PumpDriver
|
||||
@IntoMap
|
||||
@IntKey(148)
|
||||
abstract fun bindOmnipodDashPumpPlugin(plugin: OmnipodDashPumpPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@PumpDriver
|
||||
@IntoMap
|
||||
|
@ -160,7 +180,7 @@ abstract class PluginsModule {
|
|||
@PumpDriver
|
||||
@IntoMap
|
||||
@IntKey(155)
|
||||
abstract fun bindOmnipodPumpPlugin(plugin: OmnipodPumpPlugin): PluginBase
|
||||
abstract fun bindDiaconnG8Plugin(plugin: DiaconnG8Plugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
|
@ -195,12 +215,6 @@ abstract class PluginsModule {
|
|||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(230)
|
||||
abstract fun bindNSProfilePlugin(plugin: NSProfilePlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
@IntKey(240)
|
||||
abstract fun bindLocalProfilePlugin(plugin: LocalProfilePlugin): PluginBase
|
||||
|
||||
|
@ -210,12 +224,6 @@ abstract class PluginsModule {
|
|||
@IntKey(250)
|
||||
abstract fun bindAutomationPlugin(plugin: AutomationPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(260)
|
||||
abstract fun bindTreatmentsPlugin(plugin: TreatmentsPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
|
@ -270,12 +278,6 @@ abstract class PluginsModule {
|
|||
@IntKey(340)
|
||||
abstract fun bindStatusLinePlugin(plugin: StatusLinePlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(350)
|
||||
abstract fun bindPersistentNotificationPlugin(plugin: PersistentNotificationPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
|
@ -294,6 +296,12 @@ abstract class PluginsModule {
|
|||
@IntKey(380)
|
||||
abstract fun bindDstHelperPlugin(plugin: DstHelperPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(381)
|
||||
abstract fun bindBgQualityCheckPlugin(plugin: BgQualityCheckPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
|
@ -346,13 +354,25 @@ abstract class PluginsModule {
|
|||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(470)
|
||||
abstract fun bindGlunovoPlugin(plugin: GlunovoPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
@IntKey(475)
|
||||
abstract fun bindRandomBgPlugin(plugin: RandomBgPlugin): PluginBase
|
||||
|
||||
// @Binds
|
||||
// @NotNSClient
|
||||
// @IntoMap
|
||||
// @IntKey(480)
|
||||
// abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
|
||||
|
||||
@Binds
|
||||
@NotNSClient
|
||||
@IntoMap
|
||||
@IntKey(480)
|
||||
abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
|
||||
abstract fun bindsOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
|
@ -0,0 +1,16 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat
|
||||
import info.nightscout.androidaps.utils.CryptoUtil
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class PreferencesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun cryptoUtilInjector(): CryptoUtil
|
||||
@ContributesAndroidInjector abstract fun encryptedPrefsFormatInjector(): EncryptedPrefsFormat
|
||||
@ContributesAndroidInjector abstract fun prefImportListProviderInjector(): PrefFileListProvider
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
|
@ -17,6 +17,7 @@ abstract class ReceiversModule {
|
|||
@ContributesAndroidInjector abstract fun contributesChargingStateReceiver(): ChargingStateReceiver
|
||||
@ContributesAndroidInjector abstract fun contributesDataReceiver(): DataReceiver
|
||||
@ContributesAndroidInjector abstract fun contributesKeepAliveReceiver(): KeepAliveReceiver
|
||||
@ContributesAndroidInjector abstract fun contributesKeepAliveWorker(): KeepAliveReceiver.KeepAliveWorker
|
||||
@ContributesAndroidInjector abstract fun contributesRileyLinkBluetoothStateReceiver(): RileyLinkBluetoothStateReceiver
|
||||
@ContributesAndroidInjector abstract fun contributesSmsReceiver(): SmsReceiver
|
||||
@ContributesAndroidInjector abstract fun contributesTimeDateOrTZChangeReceiver(): TimeDateOrTZChangeReceiver
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
|
@ -0,0 +1,22 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.services.NSClientService
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.DismissNotificationService
|
||||
import info.nightscout.androidaps.plugins.general.persistentNotification.DummyService
|
||||
import info.nightscout.androidaps.plugins.general.wear.wearintegration.WatchUpdaterService
|
||||
import info.nightscout.androidaps.services.AlarmSoundService
|
||||
import info.nightscout.androidaps.services.LocationService
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class ServicesModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesAlarmSoundService(): AlarmSoundService
|
||||
@ContributesAndroidInjector abstract fun contributesDismissNotificationService(): DismissNotificationService
|
||||
@ContributesAndroidInjector abstract fun contributesDummyService(): DummyService
|
||||
@ContributesAndroidInjector abstract fun contributesLocationService(): LocationService
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientService(): NSClientService
|
||||
@ContributesAndroidInjector abstract fun contributesWatchUpdaterService(): WatchUpdaterService
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.multibindings.IntKey
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.dependencyInjection
|
||||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
|
@ -13,12 +13,15 @@ abstract class WizardModule {
|
|||
@ContributesAndroidInjector abstract fun swBreakInjector(): SWBreak
|
||||
@ContributesAndroidInjector abstract fun swButtonInjector(): SWButton
|
||||
@ContributesAndroidInjector abstract fun swEditNumberWithUnitsInjector(): SWEditNumberWithUnits
|
||||
@ContributesAndroidInjector abstract fun swEditNumberInjector(): SWEditNumber
|
||||
@ContributesAndroidInjector abstract fun swEditIntNumberInjector(): SWEditIntNumber
|
||||
@ContributesAndroidInjector abstract fun swEditStringInjector(): SWEditString
|
||||
@ContributesAndroidInjector abstract fun swEditEncryptedPasswordInjector(): SWEditEncryptedPassword
|
||||
@ContributesAndroidInjector abstract fun swEditUrlInjector(): SWEditUrl
|
||||
@ContributesAndroidInjector abstract fun swFragmentInjector(): SWFragment
|
||||
@ContributesAndroidInjector abstract fun swPreferenceInjector(): SWPreference
|
||||
@ContributesAndroidInjector abstract fun swHtmlLinkInjector(): SWHtmlLink
|
||||
@ContributesAndroidInjector abstract fun swInfotextInjector(): SWInfotext
|
||||
@ContributesAndroidInjector abstract fun swInfotextInjector(): SWInfoText
|
||||
@ContributesAndroidInjector abstract fun swItemInjector(): SWItem
|
||||
@ContributesAndroidInjector abstract fun swPluginInjector(): SWPlugin
|
||||
@ContributesAndroidInjector abstract fun swRadioButtonInjector(): SWRadioButton
|
|
@ -0,0 +1,35 @@
|
|||
package info.nightscout.androidaps.di
|
||||
|
||||
import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
|
||||
import info.nightscout.androidaps.plugins.general.maintenance.ImportExportPrefsImpl
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddAckWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientAddUpdateWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientMbgWorker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSClientUpdateRemoveAckWorker
|
||||
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
|
||||
import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
|
||||
import info.nightscout.androidaps.plugins.source.*
|
||||
|
||||
@Module
|
||||
@Suppress("unused")
|
||||
abstract class WorkersModule {
|
||||
|
||||
@ContributesAndroidInjector abstract fun contributesXdripWorker(): XdripPlugin.XdripWorker
|
||||
@ContributesAndroidInjector abstract fun contributesDexcomWorker(): DexcomPlugin.DexcomWorker
|
||||
@ContributesAndroidInjector abstract fun contributesMM640gWorker(): MM640gPlugin.MM640gWorker
|
||||
@ContributesAndroidInjector abstract fun contributesGlimpWorker(): GlimpPlugin.GlimpWorker
|
||||
@ContributesAndroidInjector abstract fun contributesPoctechWorker(): PoctechPlugin.PoctechWorker
|
||||
@ContributesAndroidInjector abstract fun contributesTomatoWorker(): TomatoPlugin.TomatoWorker
|
||||
@ContributesAndroidInjector abstract fun contributesEversenseWorker(): EversensePlugin.EversenseWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientSourceWorker(): NSClientSourcePlugin.NSClientSourceWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSProfileWorker(): LocalProfilePlugin.NSProfileWorker
|
||||
@ContributesAndroidInjector abstract fun contributesSmsCommunicatorWorker(): SmsCommunicatorPlugin.SmsCommunicatorWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientWorker(): NSClientAddUpdateWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientAddAckWorker(): NSClientAddAckWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientUpdateRemoveAckWorker(): NSClientUpdateRemoveAckWorker
|
||||
@ContributesAndroidInjector abstract fun contributesNSClientMbgWorker(): NSClientMbgWorker
|
||||
@ContributesAndroidInjector abstract fun contributesFoodWorker(): FoodPlugin.FoodWorker
|
||||
@ContributesAndroidInjector abstract fun contributesCsvExportWorker(): ImportExportPrefsImpl.CsvExportWorker
|
||||
}
|
|
@ -6,14 +6,18 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import com.google.common.base.Joiner
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.databinding.DialogCalibrationBinding
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.XdripCalibrations
|
||||
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.text.DecimalFormat
|
||||
|
@ -23,9 +27,11 @@ import javax.inject.Inject
|
|||
class CalibrationDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var xdripCalibrations: XdripCalibrations
|
||||
@Inject lateinit var xDripBroadcast: XDripBroadcast
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
|
||||
private var _binding: DialogCalibrationBinding? = null
|
||||
|
||||
|
@ -49,15 +55,15 @@ class CalibrationDialog : DialogFragmentWithDate() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val units = profileFunction.getUnits()
|
||||
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
|
||||
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
|
||||
?: 0.0, units)
|
||||
if (units == Constants.MMOL)
|
||||
if (units == GlucoseUnit.MMOL)
|
||||
binding.bg.setParams(savedInstanceState?.getDouble("bg")
|
||||
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok)
|
||||
else
|
||||
binding.bg.setParams(savedInstanceState?.getDouble("bg")
|
||||
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
binding.units.text = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
|
||||
binding.units.text = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -68,20 +74,20 @@ class CalibrationDialog : DialogFragmentWithDate() {
|
|||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val units = profileFunction.getUnits()
|
||||
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
|
||||
val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl)
|
||||
val actions: LinkedList<String?> = LinkedList()
|
||||
val bg = binding.bg.value ?: return false
|
||||
actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel)
|
||||
val bg = binding.bg.value
|
||||
actions.add(rh.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, bg) + " " + unitLabel)
|
||||
if (bg > 0) {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
aapsLogger.debug("USER ENTRY: CALIBRATION $bg")
|
||||
xdripCalibrations.sendIntent(bg)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_calibration), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
uel.log(Action.CALIBRATION, Sources.CalibrationDialog, ValueWithUnit.fromGlucoseUnit(bg, units.asText))
|
||||
xDripBroadcast.sendCalibration(bg)
|
||||
})
|
||||
}
|
||||
} else
|
||||
activity?.let { activity ->
|
||||
OKDialog.show(activity, resourceHelper.gs(R.string.overview_calibration), resourceHelper.gs(R.string.no_action_selected))
|
||||
OKDialog.show(activity, rh.gs(R.string.overview_calibration), rh.gs(R.string.no_action_selected))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -7,45 +8,48 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogCarbsBinding
|
||||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.db.TempTarget
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.max
|
||||
|
||||
class CarbsDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var nsUpload: NSUpload
|
||||
@Inject lateinit var carbsGenerator: CarbsGenerator
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var carbTimer: CarbTimer
|
||||
@Inject lateinit var bolusTimer: BolusTimer
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -54,6 +58,8 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
private const val FAV3_DEFAULT = 20
|
||||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
validateInputs()
|
||||
|
@ -68,15 +74,15 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
val time = binding.time.value.toInt()
|
||||
if (time > 12 * 60 || time < -12 * 60) {
|
||||
binding.time.value = 0.0
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.constraintapllied))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.constraintapllied))
|
||||
}
|
||||
if (binding.duration.value > 10) {
|
||||
binding.duration.value = 0.0
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.constraintapllied))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.constraintapllied))
|
||||
}
|
||||
if (binding.carbs.value.toInt() > maxCarbs) {
|
||||
binding.carbs.value = 0.0
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.carbsconstraintapplied))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.carbsconstraintapplied))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -93,48 +99,80 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
savedInstanceState.putDouble("carbs", binding.carbs.value)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
onCreateViewGeneral()
|
||||
_binding = DialogCarbsBinding.inflate(inflater, container, false)
|
||||
binding.time.setOnValueChangedListener { timeOffset: Double ->
|
||||
run {
|
||||
val newTime = eventTimeOriginal + timeOffset.toLong() * 1000 * 60
|
||||
updateDateTime(newTime)
|
||||
}
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
if (sp.getBoolean(R.string.key_usebolusreminder, false)) {
|
||||
glucoseStatusProvider.glucoseStatusData?.let { glucoseStatus ->
|
||||
if (glucoseStatus.glucose + 3 * glucoseStatus.delta < 70.0)
|
||||
binding.bolusReminder.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
val maxCarbs = constraintChecker.getMaxCarbsAllowed().value().toDouble()
|
||||
binding.time.setParams(savedInstanceState?.getDouble("time")
|
||||
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher)
|
||||
binding.time.setParams(
|
||||
savedInstanceState?.getDouble("time")
|
||||
?: 0.0, -12 * 60.0, 12 * 60.0, 5.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher
|
||||
)
|
||||
|
||||
binding.duration.setParams(savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, 10.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher)
|
||||
binding.duration.setParams(
|
||||
savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, 10.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher
|
||||
)
|
||||
|
||||
binding.carbs.setParams(savedInstanceState?.getDouble("carbs")
|
||||
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher)
|
||||
binding.carbs.setParams(
|
||||
savedInstanceState?.getDouble("carbs")
|
||||
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher
|
||||
)
|
||||
|
||||
binding.plus1.text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
|
||||
binding.plus1.setOnClickListener {
|
||||
binding.carbs.value = max(0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT))
|
||||
binding.carbs.value = max(
|
||||
0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_1, FAV1_DEFAULT)
|
||||
)
|
||||
validateInputs()
|
||||
}
|
||||
|
||||
binding.plus2.text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
|
||||
binding.plus2.setOnClickListener {
|
||||
binding.carbs.value = max(0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT))
|
||||
binding.carbs.value = max(
|
||||
0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_2, FAV2_DEFAULT)
|
||||
)
|
||||
validateInputs()
|
||||
}
|
||||
|
||||
binding.plus3.text = toSignedString(sp.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
|
||||
binding.plus3.setOnClickListener {
|
||||
binding.carbs.value = max(0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT))
|
||||
binding.carbs.value = max(
|
||||
0.0, binding.carbs.value
|
||||
+ sp.getInt(R.string.key_carbs_button_increment_3, FAV3_DEFAULT)
|
||||
)
|
||||
validateInputs()
|
||||
}
|
||||
|
||||
iobCobCalculatorPlugin.actualBg()?.let { bgReading ->
|
||||
setOnValueChangedListener { eventTime: Long ->
|
||||
run {
|
||||
val timeOffset = ((eventTime - eventTimeOriginal) / (1000 * 60)).toDouble()
|
||||
binding.time.value = timeOffset
|
||||
}
|
||||
}
|
||||
|
||||
iobCobCalculator.ads.actualBg()?.let { bgReading ->
|
||||
if (bgReading.value < 72)
|
||||
binding.hypoTt.isChecked = true
|
||||
}
|
||||
|
@ -154,6 +192,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
|
@ -163,7 +202,7 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val carbs = binding.carbs.value?.toInt() ?: return false
|
||||
val carbs = binding.carbs.value.toInt()
|
||||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
|
||||
val units = profileFunction.getUnits()
|
||||
val activityTTDuration = defaultValueHelper.determineActivityTTDuration()
|
||||
|
@ -173,93 +212,158 @@ class CarbsDialog : DialogFragmentWithDate() {
|
|||
val hypoTTDuration = defaultValueHelper.determineHypoTTDuration()
|
||||
val hypoTT = defaultValueHelper.determineHypoTT()
|
||||
val actions: LinkedList<String?> = LinkedList()
|
||||
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
|
||||
val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl)
|
||||
val useAlarm = binding.alarmCheckBox.isChecked
|
||||
val remindBolus = binding.bolusReminderCheckBox.isChecked
|
||||
|
||||
val activitySelected = binding.activityTt.isChecked
|
||||
if (activitySelected)
|
||||
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, activityTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation))
|
||||
actions.add(
|
||||
rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(activityTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, activityTTDuration) + ")").formatColor(
|
||||
rh,
|
||||
R.color.tempTargetConfirmation
|
||||
)
|
||||
)
|
||||
val eatingSoonSelected = binding.eatingSoonTt.isChecked
|
||||
if (eatingSoonSelected)
|
||||
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, eatingSoonTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation))
|
||||
actions.add(
|
||||
rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs(
|
||||
R.string.format_mins,
|
||||
eatingSoonTTDuration
|
||||
) + ")").formatColor(rh, R.color.tempTargetConfirmation)
|
||||
)
|
||||
val hypoSelected = binding.hypoTt.isChecked
|
||||
if (hypoSelected)
|
||||
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, hypoTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation))
|
||||
actions.add(
|
||||
rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(hypoTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, hypoTTDuration) + ")").formatColor(
|
||||
rh,
|
||||
R.color.tempTargetConfirmation
|
||||
)
|
||||
)
|
||||
|
||||
val timeOffset = binding.time.value.toInt()
|
||||
eventTime -= eventTime % 1000
|
||||
val time = eventTime + timeOffset * 1000 * 60
|
||||
if (timeOffset != 0)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time))
|
||||
if (useAlarm && carbs > 0 && timeOffset > 0)
|
||||
actions.add(rh.gs(R.string.alarminxmin, timeOffset).formatColor(rh, R.color.info))
|
||||
val duration = binding.duration.value.toInt()
|
||||
if (duration > 0)
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + duration + resourceHelper.gs(R.string.shorthour))
|
||||
actions.add(rh.gs(R.string.duration) + ": " + duration + rh.gs(R.string.shorthour))
|
||||
if (carbsAfterConstraints > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.carbs) + ": " + "<font color='" + resourceHelper.gc(R.color.carbs) + "'>" + resourceHelper.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
|
||||
actions.add(rh.gs(R.string.carbs) + ": " + "<font color='" + rh.gc(R.color.carbs) + "'>" + rh.gs(R.string.format_carbs, carbsAfterConstraints) + "</font>")
|
||||
if (carbsAfterConstraints != carbs)
|
||||
actions.add("<font color='" + resourceHelper.gc(R.color.warning) + "'>" + resourceHelper.gs(R.string.carbsconstraintapplied) + "</font>")
|
||||
actions.add("<font color='" + rh.gc(R.color.warning) + "'>" + rh.gs(R.string.carbsconstraintapplied) + "</font>")
|
||||
}
|
||||
val notes = binding.notesLayout.notes.text.toString()
|
||||
if (notes.isNotEmpty())
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||
actions.add(rh.gs(R.string.notes_label) + ": " + notes)
|
||||
|
||||
if (eventTimeChanged)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
|
||||
if (carbsAfterConstraints > 0 || activitySelected || eatingSoonSelected || hypoSelected) {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.carbs), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
when {
|
||||
activitySelected -> {
|
||||
aapsLogger.debug("USER ENTRY: TEMPTARGET ACTIVITY $activityTT duration: $activityTTDuration")
|
||||
val tempTarget = TempTarget()
|
||||
.date(System.currentTimeMillis())
|
||||
.duration(activityTTDuration)
|
||||
.reason(resourceHelper.gs(R.string.activity))
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(activityTT, profileFunction.getUnits()))
|
||||
.high(Profile.toMgdl(activityTT, profileFunction.getUnits()))
|
||||
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
|
||||
uel.log(
|
||||
Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY),
|
||||
ValueWithUnit.fromGlucoseUnit(activityTT, units.asText),
|
||||
ValueWithUnit.Minute(activityTTDuration)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(
|
||||
InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
duration = TimeUnit.MINUTES.toMillis(activityTTDuration.toLong()),
|
||||
reason = TemporaryTarget.Reason.ACTIVITY,
|
||||
lowTarget = Profile.toMgdl(activityTT, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(activityTT, profileFunction.getUnits())
|
||||
)
|
||||
).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
}
|
||||
|
||||
eatingSoonSelected -> {
|
||||
aapsLogger.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
|
||||
val tempTarget = TempTarget()
|
||||
.date(System.currentTimeMillis())
|
||||
.duration(eatingSoonTTDuration)
|
||||
.reason(resourceHelper.gs(R.string.eatingsoon))
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()))
|
||||
.high(Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()))
|
||||
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
|
||||
uel.log(
|
||||
Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON),
|
||||
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units.asText),
|
||||
ValueWithUnit.Minute(eatingSoonTTDuration)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(
|
||||
InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()),
|
||||
reason = TemporaryTarget.Reason.EATING_SOON,
|
||||
lowTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits())
|
||||
)
|
||||
).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
}
|
||||
|
||||
hypoSelected -> {
|
||||
aapsLogger.debug("USER ENTRY: TEMPTARGET HYPO $hypoTT duration: $hypoTTDuration")
|
||||
val tempTarget = TempTarget()
|
||||
.date(System.currentTimeMillis())
|
||||
.duration(hypoTTDuration)
|
||||
.reason(resourceHelper.gs(R.string.hypo))
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(hypoTT, profileFunction.getUnits()))
|
||||
.high(Profile.toMgdl(hypoTT, profileFunction.getUnits()))
|
||||
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
|
||||
uel.log(
|
||||
Action.TT, Sources.CarbDialog,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA),
|
||||
ValueWithUnit.fromGlucoseUnit(hypoTT, units.asText),
|
||||
ValueWithUnit.Minute(hypoTTDuration)
|
||||
)
|
||||
disposable += repository.runTransactionForResult(
|
||||
InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
duration = TimeUnit.MINUTES.toMillis(hypoTTDuration.toLong()),
|
||||
reason = TemporaryTarget.Reason.HYPOGLYCEMIA,
|
||||
lowTarget = Profile.toMgdl(hypoTT, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(hypoTT, profileFunction.getUnits())
|
||||
)
|
||||
).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
}
|
||||
}
|
||||
if (carbsAfterConstraints > 0) {
|
||||
if (duration == 0) {
|
||||
aapsLogger.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time")
|
||||
carbsGenerator.createCarb(carbsAfterConstraints, time, CareportalEvent.CARBCORRECTION, notes)
|
||||
} else {
|
||||
aapsLogger.debug("USER ENTRY: CARBS $carbsAfterConstraints time: $time duration: $duration")
|
||||
carbsGenerator.generateCarbs(carbsAfterConstraints, time, duration, notes)
|
||||
nsUpload.uploadEvent(CareportalEvent.NOTE, DateUtil.now() - 2000, resourceHelper.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset))
|
||||
val detailedBolusInfo = DetailedBolusInfo()
|
||||
detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS
|
||||
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
|
||||
detailedBolusInfo.context = context
|
||||
detailedBolusInfo.notes = notes
|
||||
detailedBolusInfo.carbsDuration = T.hours(duration.toLong()).msecs()
|
||||
detailedBolusInfo.carbsTimestamp = eventTime
|
||||
uel.log(if (duration == 0) Action.CARBS else Action.EXTENDED_CARBS, Sources.CarbDialog,
|
||||
notes,
|
||||
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
|
||||
ValueWithUnit.Gram(carbsAfterConstraints),
|
||||
ValueWithUnit.Minute(timeOffset).takeIf { timeOffset != 0 },
|
||||
ValueWithUnit.Hour(duration).takeIf { duration != 0 })
|
||||
commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||
override fun run() {
|
||||
carbTimer.removeEatReminder()
|
||||
if (!result.success) {
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror)
|
||||
} else if (sp.getBoolean(R.string.key_usebolusreminder, false) && remindBolus)
|
||||
bolusTimer.scheduleBolusReminder()
|
||||
}
|
||||
})
|
||||
}
|
||||
if (useAlarm && carbs > 0 && timeOffset > 0) {
|
||||
carbTimer.scheduleReminder(T.mins(timeOffset.toLong()).secs().toInt())
|
||||
}
|
||||
}, null)
|
||||
}
|
||||
} else
|
||||
activity?.let { activity ->
|
||||
OKDialog.show(activity, resourceHelper.gs(R.string.carbs), resourceHelper.gs(R.string.no_action_selected))
|
||||
OKDialog.show(activity, rh.gs(R.string.carbs), rh.gs(R.string.no_action_selected))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -10,21 +11,28 @@ import androidx.annotation.StringRes
|
|||
import com.google.common.base.Joiner
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogCareBinding
|
||||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.Translator
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.extensions.fromConstant
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.json.JSONObject
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
@ -32,11 +40,15 @@ import javax.inject.Inject
|
|||
class CareDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var nsUpload: NSUpload
|
||||
@Inject lateinit var translator: Translator
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
enum class EventType {
|
||||
BGCHECK,
|
||||
|
@ -49,6 +61,8 @@ class CareDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
|
||||
private var options: EventType = EventType.BGCHECK
|
||||
//private var valuesWithUnit = mutableListOf<XXXValueWithUnit?>()
|
||||
private var valuesWithUnit = mutableListOf<ValueWithUnit?>()
|
||||
|
||||
@StringRes
|
||||
private var event: Int = R.string.none
|
||||
|
@ -97,7 +111,7 @@ class CareDialog : DialogFragmentWithDate() {
|
|||
EventType.QUESTION -> R.drawable.ic_cp_question
|
||||
EventType.ANNOUNCEMENT -> R.drawable.ic_cp_announcement
|
||||
})
|
||||
binding.title.text = resourceHelper.gs(when (options) {
|
||||
binding.title.text = rh.gs(when (options) {
|
||||
EventType.BGCHECK -> R.string.careportal_bgcheck
|
||||
EventType.SENSOR_INSERT -> R.string.careportal_cgmsensorinsert
|
||||
EventType.BATTERY_CHANGE -> R.string.careportal_pumpbatterychange
|
||||
|
@ -128,7 +142,7 @@ class CareDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
}
|
||||
|
||||
val bg = Profile.fromMgdlToUnits(GlucoseStatus(injector).glucoseStatusData?.glucose
|
||||
val bg = Profile.fromMgdlToUnits(glucoseStatusProvider.glucoseStatusData?.glucose
|
||||
?: 0.0, profileFunction.getUnits())
|
||||
val bgTextWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {}
|
||||
|
@ -138,18 +152,18 @@ class CareDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
}
|
||||
|
||||
if (profileFunction.getUnits() == Constants.MMOL) {
|
||||
binding.bgunits.text = resourceHelper.gs(R.string.mmol)
|
||||
if (profileFunction.getUnits() == GlucoseUnit.MMOL) {
|
||||
binding.bgUnits.text = rh.gs(R.string.mmol)
|
||||
binding.bg.setParams(savedInstanceState?.getDouble("bg")
|
||||
?: bg, 2.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok, bgTextWatcher)
|
||||
} else {
|
||||
binding.bgunits.text = resourceHelper.gs(R.string.mgdl)
|
||||
binding.bgUnits.text = rh.gs(R.string.mgdl)
|
||||
binding.bg.setParams(savedInstanceState?.getDouble("bg")
|
||||
?: bg, 36.0, 500.0, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, bgTextWatcher)
|
||||
}
|
||||
binding.duration.setParams(savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
if (options == EventType.NOTE || options == EventType.QUESTION || options == EventType.ANNOUNCEMENT)
|
||||
if (options == EventType.NOTE || options == EventType.QUESTION || options == EventType.ANNOUNCEMENT || options == EventType.EXERCISE)
|
||||
binding.notesLayout.root.visibility = View.VISIBLE // independent to preferences
|
||||
}
|
||||
|
||||
|
@ -159,70 +173,75 @@ class CareDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
|
||||
override fun submit(): Boolean {
|
||||
val enteredBy = sp.getString("careportal_enteredby", "")
|
||||
val unitResId = if (profileFunction.getUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
|
||||
val enteredBy = sp.getString("careportal_enteredby", "AndroidAPS")
|
||||
val unitResId = if (profileFunction.getUnits() == GlucoseUnit.MGDL) R.string.mgdl else R.string.mmol
|
||||
|
||||
eventTime -= eventTime % 1000
|
||||
|
||||
val therapyEvent = TherapyEvent(
|
||||
timestamp = eventTime,
|
||||
type = when (options) {
|
||||
EventType.BGCHECK -> TherapyEvent.Type.FINGER_STICK_BG_VALUE
|
||||
EventType.SENSOR_INSERT -> TherapyEvent.Type.SENSOR_CHANGE
|
||||
EventType.BATTERY_CHANGE -> TherapyEvent.Type.PUMP_BATTERY_CHANGE
|
||||
EventType.NOTE -> TherapyEvent.Type.NOTE
|
||||
EventType.EXERCISE -> TherapyEvent.Type.EXERCISE
|
||||
EventType.QUESTION -> TherapyEvent.Type.QUESTION
|
||||
EventType.ANNOUNCEMENT -> TherapyEvent.Type.ANNOUNCEMENT
|
||||
},
|
||||
glucoseUnit = TherapyEvent.GlucoseUnit.fromConstant(profileFunction.getUnits())
|
||||
)
|
||||
|
||||
val json = JSONObject()
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
if (options == EventType.BGCHECK || options == EventType.QUESTION || options == EventType.ANNOUNCEMENT) {
|
||||
val type =
|
||||
val meterType =
|
||||
when {
|
||||
binding.meter.isChecked -> CareportalEvent.FINGER
|
||||
binding.sensor.isChecked -> CareportalEvent.SENSOR
|
||||
else -> CareportalEvent.MANUAL
|
||||
binding.meter.isChecked -> TherapyEvent.MeterType.FINGER
|
||||
binding.sensor.isChecked -> TherapyEvent.MeterType.SENSOR
|
||||
else -> TherapyEvent.MeterType.MANUAL
|
||||
}
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(type))
|
||||
actions.add(resourceHelper.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, binding.bg.value) + " " + resourceHelper.gs(unitResId))
|
||||
json.put("glucose", binding.bg.value)
|
||||
json.put("glucoseType", type)
|
||||
actions.add(rh.gs(R.string.careportal_newnstreatment_glucosetype) + ": " + translator.translate(meterType))
|
||||
actions.add(rh.gs(R.string.treatments_wizard_bg_label) + ": " + Profile.toCurrentUnitsString(profileFunction, binding.bg.value) + " " + rh.gs(unitResId))
|
||||
therapyEvent.glucoseType = meterType
|
||||
therapyEvent.glucose = binding.bg.value
|
||||
valuesWithUnit.add(ValueWithUnit.fromGlucoseUnit(binding.bg.value, profileFunction.getUnits().asText))
|
||||
valuesWithUnit.add(ValueWithUnit.TherapyEventMeterType(meterType))
|
||||
}
|
||||
if (options == EventType.NOTE || options == EventType.EXERCISE) {
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_duration_label) + ": " + resourceHelper.gs(R.string.format_mins, binding.duration.value.toInt()))
|
||||
json.put("duration", binding.duration.value.toInt())
|
||||
actions.add(rh.gs(R.string.careportal_newnstreatment_duration_label) + ": " + rh.gs(R.string.format_mins, binding.duration.value.toInt()))
|
||||
therapyEvent.duration = T.mins(binding.duration.value.toLong()).msecs()
|
||||
valuesWithUnit.add(ValueWithUnit.Minute(binding.duration.value.toInt()).takeIf { !binding.duration.value.equals(0.0) } )
|
||||
}
|
||||
val notes = binding.notesLayout.notes.text.toString()
|
||||
if (notes.isNotEmpty()) {
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||
json.put("notes", notes)
|
||||
actions.add(rh.gs(R.string.notes_label) + ": " + notes)
|
||||
therapyEvent.note = notes
|
||||
}
|
||||
eventTime -= eventTime % 1000
|
||||
|
||||
if (eventTimeChanged)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
if (eventTimeChanged) actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
|
||||
json.put("created_at", DateUtil.toISOString(eventTime))
|
||||
json.put("mills", eventTime)
|
||||
json.put("eventType", when (options) {
|
||||
EventType.BGCHECK -> CareportalEvent.BGCHECK
|
||||
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
|
||||
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
|
||||
EventType.NOTE -> CareportalEvent.NOTE
|
||||
EventType.EXERCISE -> CareportalEvent.EXERCISE
|
||||
EventType.QUESTION -> CareportalEvent.QUESTION
|
||||
EventType.ANNOUNCEMENT -> CareportalEvent.ANNOUNCEMENT
|
||||
})
|
||||
json.put("units", profileFunction.getUnits())
|
||||
if (enteredBy.isNotEmpty())
|
||||
json.put("enteredBy", enteredBy)
|
||||
therapyEvent.enteredBy = enteredBy
|
||||
|
||||
val source = when (options) {
|
||||
EventType.BGCHECK -> Sources.BgCheck
|
||||
EventType.SENSOR_INSERT -> Sources.SensorInsert
|
||||
EventType.BATTERY_CHANGE -> Sources.BatteryChange
|
||||
EventType.NOTE -> Sources.Note
|
||||
EventType.EXERCISE -> Sources.Exercise
|
||||
EventType.QUESTION -> Sources.Question
|
||||
EventType.ANNOUNCEMENT -> Sources.Announcement
|
||||
}
|
||||
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(event), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
val careportalEvent = CareportalEvent(injector)
|
||||
careportalEvent.date = eventTime
|
||||
careportalEvent.source = Source.USER
|
||||
careportalEvent.eventType = when (options) {
|
||||
EventType.BGCHECK -> CareportalEvent.BGCHECK
|
||||
EventType.SENSOR_INSERT -> CareportalEvent.SENSORCHANGE
|
||||
EventType.BATTERY_CHANGE -> CareportalEvent.PUMPBATTERYCHANGE
|
||||
EventType.NOTE -> CareportalEvent.NOTE
|
||||
EventType.EXERCISE -> CareportalEvent.EXERCISE
|
||||
EventType.QUESTION -> CareportalEvent.QUESTION
|
||||
EventType.ANNOUNCEMENT -> CareportalEvent.ANNOUNCEMENT
|
||||
}
|
||||
careportalEvent.json = json.toString()
|
||||
aapsLogger.debug("USER ENTRY: CAREPORTAL ${careportalEvent.eventType} json: ${careportalEvent.json}")
|
||||
MainApp.getDbHelper().createOrUpdate(careportalEvent)
|
||||
nsUpload.uploadCareportalEntryToNS(json)
|
||||
OKDialog.showConfirmation(activity, rh.gs(event), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
disposable += repository.runTransactionForResult(InsertIfNewByTimestampTherapyEventTransaction(therapyEvent))
|
||||
.subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) }
|
||||
)
|
||||
valuesWithUnit.add(0, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged })
|
||||
valuesWithUnit.add(1, ValueWithUnit.TherapyEventType(therapyEvent.type))
|
||||
uel.log(Action.CAREPORTAL, source, notes, valuesWithUnit)
|
||||
}, null)
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -1,145 +0,0 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.app.TimePickerDialog
|
||||
import android.os.Bundle
|
||||
import android.text.format.DateFormat
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import android.widget.Button
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import dagger.android.support.DaggerDialogFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class DialogFragmentWithDate : DaggerDialogFragment() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
var eventTime = DateUtil.now()
|
||||
var eventTimeChanged = false
|
||||
|
||||
//one shot guards
|
||||
private var okClicked: Boolean = false
|
||||
|
||||
companion object {
|
||||
|
||||
private var seconds: Int = (Math.random() * 59.0).toInt()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putLong("eventTime", eventTime)
|
||||
savedInstanceState.putBoolean("eventTimeChanged", eventTimeChanged)
|
||||
}
|
||||
|
||||
fun onCreateViewGeneral() {
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
isCancelable = true
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
val eventDateView = view.findViewById(R.id.eventdate) as TextView?
|
||||
val eventTimeView = view.findViewById(R.id.eventtime) as TextView?
|
||||
|
||||
eventTime = savedInstanceState?.getLong("eventTime") ?: DateUtil.now()
|
||||
eventTimeChanged = savedInstanceState?.getBoolean("eventTimeChanged") ?: false
|
||||
|
||||
eventDateView?.text = DateUtil.dateString(eventTime)
|
||||
eventTimeView?.text = dateUtil.timeString(eventTime)
|
||||
|
||||
// create an OnDateSetListener
|
||||
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = eventTime
|
||||
cal.set(Calendar.YEAR, year)
|
||||
cal.set(Calendar.MONTH, monthOfYear)
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||
eventTime = cal.timeInMillis
|
||||
eventTimeChanged = true
|
||||
eventDateView?.text = DateUtil.dateString(eventTime)
|
||||
}
|
||||
|
||||
eventDateView?.setOnClickListener {
|
||||
context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = eventTime
|
||||
DatePickerDialog(it, dateSetListener,
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
// create an OnTimeSetListener
|
||||
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = eventTime
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||
cal.set(Calendar.MINUTE, minute)
|
||||
cal.set(Calendar.SECOND, seconds++) // randomize seconds to prevent creating record of the same time, if user choose time manually
|
||||
eventTime = cal.timeInMillis
|
||||
eventTimeChanged = true
|
||||
eventTimeView?.text = dateUtil.timeString(eventTime)
|
||||
}
|
||||
|
||||
eventTimeView?.setOnClickListener {
|
||||
context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = eventTime
|
||||
TimePickerDialog(it, timeSetListener,
|
||||
cal.get(Calendar.HOUR_OF_DAY),
|
||||
cal.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(context)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
(view.findViewById(R.id.notes_layout) as View?)?.visibility = sp.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||
|
||||
(view.findViewById(R.id.ok) as Button?)?.setOnClickListener {
|
||||
synchronized(okClicked) {
|
||||
if (okClicked) {
|
||||
aapsLogger.warn(LTag.UI, "guarding: ok already clicked")
|
||||
} else {
|
||||
okClicked = true
|
||||
if (submit()) dismiss()
|
||||
else okClicked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
(view.findViewById(R.id.cancel) as Button?)?.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
override fun show(manager: FragmentManager, tag: String?) {
|
||||
try {
|
||||
manager.beginTransaction().let {
|
||||
it.add(this, tag)
|
||||
it.commitAllowingStateLoss()
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
aapsLogger.debug(e.localizedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
abstract fun submit(): Boolean
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -9,16 +8,20 @@ import android.view.ViewGroup
|
|||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.DialogExtendedbolusBinding
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.CommandQueue
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
@ -28,10 +31,11 @@ import kotlin.math.abs
|
|||
class ExtendedBolusDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
private var _binding: DialogExtendedbolusBinding? = null
|
||||
|
||||
|
@ -75,27 +79,24 @@ class ExtendedBolusDialog : DialogFragmentWithDate() {
|
|||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val insulin = SafeParse.stringToDouble(binding.insulin.text ?: return false)
|
||||
val insulin = SafeParse.stringToDouble(binding.insulin.text)
|
||||
val durationInMinutes = binding.duration.value.toInt()
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
val insulinAfterConstraint = constraintChecker.applyExtendedBolusConstraints(Constraint(insulin)).value()
|
||||
actions.add(resourceHelper.gs(R.string.formatinsulinunits, insulinAfterConstraint))
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, durationInMinutes))
|
||||
actions.add(rh.gs(R.string.formatinsulinunits, insulinAfterConstraint))
|
||||
actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes))
|
||||
if (abs(insulinAfterConstraint - insulin) > 0.01)
|
||||
actions.add(resourceHelper.gs(R.string.constraintapllied).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.constraintapllied).formatColor(rh, R.color.warning))
|
||||
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
aapsLogger.debug("USER ENTRY: EXTENDED BOLUS $insulinAfterConstraint duration: $durationInMinutes")
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.extended_bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
uel.log(Action.EXTENDED_BOLUS, Sources.ExtendedBolusDialog,
|
||||
ValueWithUnit.Insulin(insulinAfterConstraint),
|
||||
ValueWithUnit.Minute(durationInMinutes))
|
||||
commandQueue.extendedBolus(insulinAfterConstraint, durationInMinutes, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -10,21 +9,28 @@ import com.google.common.base.Joiner
|
|||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.transactions.InsertIfNewByTimestampTherapyEventTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogFillBinding
|
||||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.CommandQueue
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
@ -32,11 +38,14 @@ import kotlin.math.abs
|
|||
class FillDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var nsUpload: NSUpload
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var _binding: DialogFillBinding? = null
|
||||
|
||||
|
@ -97,52 +106,76 @@ class FillDialog : DialogFragmentWithDate() {
|
|||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val insulin = SafeParse.stringToDouble(binding.fillInsulinamount.text ?: return false)
|
||||
val insulin = SafeParse.stringToDouble(binding.fillInsulinamount.text)
|
||||
val actions: LinkedList<String?> = LinkedList()
|
||||
|
||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value()
|
||||
if (insulinAfterConstraints > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.fillwarning))
|
||||
actions.add(rh.gs(R.string.fillwarning))
|
||||
actions.add("")
|
||||
actions.add(resourceHelper.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, resourceHelper).formatColor(resourceHelper, R.color.colorInsulinButton))
|
||||
actions.add(rh.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, rh).formatColor(rh, R.color.colorInsulinButton))
|
||||
if (abs(insulinAfterConstraints - insulin) > 0.01)
|
||||
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(rh, R.color.warning))
|
||||
}
|
||||
val siteChange = binding.fillCatheterChange.isChecked
|
||||
if (siteChange)
|
||||
actions.add(resourceHelper.gs(R.string.record_pump_site_change).formatColor(resourceHelper, R.color.actionsConfirm))
|
||||
actions.add(rh.gs(R.string.record_pump_site_change).formatColor(rh, R.color.actionsConfirm))
|
||||
val insulinChange = binding.fillCartridgeChange.isChecked
|
||||
if (insulinChange)
|
||||
actions.add(resourceHelper.gs(R.string.record_insulin_cartridge_change).formatColor(resourceHelper, R.color.actionsConfirm))
|
||||
val notes = binding.notesLayout.notes.text.toString()
|
||||
actions.add(rh.gs(R.string.record_insulin_cartridge_change).formatColor(rh, R.color.actionsConfirm))
|
||||
val notes: String = binding.notesLayout.notes.text.toString()
|
||||
if (notes.isNotEmpty())
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||
actions.add(rh.gs(R.string.notes_label) + ": " + notes)
|
||||
eventTime -= eventTime % 1000
|
||||
|
||||
if (eventTimeChanged)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
|
||||
if (insulinAfterConstraints > 0 || binding.fillCatheterChange.isChecked || binding.fillCartridgeChange.isChecked) {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.primefill), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
if (insulinAfterConstraints > 0) {
|
||||
aapsLogger.debug("USER ENTRY: PRIME BOLUS $insulinAfterConstraints")
|
||||
uel.log(Action.PRIME_BOLUS, Sources.FillDialog,
|
||||
notes,
|
||||
ValueWithUnit.Insulin(insulinAfterConstraints).takeIf { insulinAfterConstraints != 0.0 })
|
||||
requestPrimeBolus(insulinAfterConstraints, notes)
|
||||
}
|
||||
if (siteChange) {
|
||||
aapsLogger.debug("USER ENTRY: SITE CHANGE")
|
||||
nsUpload.generateCareportalEvent(CareportalEvent.SITECHANGE, eventTime, notes)
|
||||
uel.log(Action.SITE_CHANGE, Sources.FillDialog,
|
||||
notes,
|
||||
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
|
||||
ValueWithUnit.TherapyEventType(TherapyEvent.Type.CANNULA_CHANGE))
|
||||
disposable += repository.runTransactionForResult(InsertIfNewByTimestampTherapyEventTransaction(
|
||||
timestamp = eventTime,
|
||||
type = TherapyEvent.Type.CANNULA_CHANGE,
|
||||
note = notes,
|
||||
glucoseUnit = TherapyEvent.GlucoseUnit.MGDL
|
||||
)).subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) }
|
||||
)
|
||||
}
|
||||
if (insulinChange) {
|
||||
// add a second for case of both checked
|
||||
aapsLogger.debug("USER ENTRY: INSULIN CHANGE")
|
||||
nsUpload.generateCareportalEvent(CareportalEvent.INSULINCHANGE, eventTime + 1000, notes)
|
||||
uel.log(Action.RESERVOIR_CHANGE, Sources.FillDialog,
|
||||
notes,
|
||||
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
|
||||
ValueWithUnit.TherapyEventType(TherapyEvent.Type.INSULIN_CHANGE))
|
||||
disposable += repository.runTransactionForResult(InsertIfNewByTimestampTherapyEventTransaction(
|
||||
timestamp = eventTime + 1000,
|
||||
type = TherapyEvent.Type.INSULIN_CHANGE,
|
||||
note = notes,
|
||||
glucoseUnit = TherapyEvent.GlucoseUnit.MGDL
|
||||
)).subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted therapy event $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving therapy event", it) }
|
||||
)
|
||||
}
|
||||
}, null)
|
||||
}
|
||||
} else {
|
||||
activity?.let { activity ->
|
||||
OKDialog.show(activity, resourceHelper.gs(R.string.primefill), resourceHelper.gs(R.string.no_action_selected))
|
||||
OKDialog.show(activity, rh.gs(R.string.primefill), rh.gs(R.string.no_action_selected))
|
||||
}
|
||||
}
|
||||
dismiss()
|
||||
|
@ -153,18 +186,12 @@ class FillDialog : DialogFragmentWithDate() {
|
|||
val detailedBolusInfo = DetailedBolusInfo()
|
||||
detailedBolusInfo.insulin = insulin
|
||||
detailedBolusInfo.context = context
|
||||
detailedBolusInfo.source = Source.USER
|
||||
detailedBolusInfo.isValid = false // do not count it in IOB (for pump history)
|
||||
detailedBolusInfo.bolusType = DetailedBolusInfo.BolusType.PRIMING
|
||||
detailedBolusInfo.notes = notes
|
||||
commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -9,30 +8,33 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogInsulinBinding
|
||||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.db.TempTarget
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.extensions.toSignedString
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.shared.SafeParse
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
|
@ -40,13 +42,16 @@ import kotlin.math.max
|
|||
class InsulinDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var bolusTimer: BolusTimer
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
companion object {
|
||||
|
||||
|
@ -55,6 +60,8 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
private const val PLUS3_DEFAULT = 2.0
|
||||
}
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
validateInputs()
|
||||
|
@ -74,11 +81,11 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
val maxInsulin = constraintChecker.getMaxBolusAllowed().value()
|
||||
if (abs(binding.time.value.toInt()) > 12 * 60) {
|
||||
binding.time.value = 0.0
|
||||
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.constraintapllied))
|
||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.constraintapllied))
|
||||
}
|
||||
if (binding.amount.value > maxInsulin) {
|
||||
binding.amount.value = 0.0
|
||||
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.bolusconstraintapplied))
|
||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.bolusconstraintapplied))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,22 +116,22 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
binding.amount.setParams(savedInstanceState?.getDouble("amount")
|
||||
?: 0.0, 0.0, maxInsulin, activePlugin.activePump.pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.okcancel.ok, textWatcher)
|
||||
|
||||
binding.plus05.text = sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus05.text = sp.getDouble(rh.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus05.setOnClickListener {
|
||||
binding.amount.value = max(0.0, binding.amount.value
|
||||
+ sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
|
||||
+ sp.getDouble(rh.gs(R.string.key_insulin_button_increment_1), PLUS1_DEFAULT))
|
||||
validateInputs()
|
||||
}
|
||||
binding.plus10.text = sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus10.text = sp.getDouble(rh.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus10.setOnClickListener {
|
||||
binding.amount.value = max(0.0, binding.amount.value
|
||||
+ sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
|
||||
+ sp.getDouble(rh.gs(R.string.key_insulin_button_increment_2), PLUS2_DEFAULT))
|
||||
validateInputs()
|
||||
}
|
||||
binding.plus20.text = sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus20.text = sp.getDouble(rh.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT).toSignedString(activePlugin.activePump)
|
||||
binding.plus20.setOnClickListener {
|
||||
binding.amount.value = max(0.0, binding.amount.value
|
||||
+ sp.getDouble(resourceHelper.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
|
||||
+ sp.getDouble(rh.gs(R.string.key_insulin_button_increment_3), PLUS3_DEFAULT))
|
||||
validateInputs()
|
||||
}
|
||||
|
||||
|
@ -136,78 +143,94 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val pumpDescription = activePlugin.activePump.pumpDescription
|
||||
val insulin = SafeParse.stringToDouble(binding.amount.text ?: return false)
|
||||
val insulin = SafeParse.stringToDouble(binding.amount.text)
|
||||
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(insulin)).value()
|
||||
val actions: LinkedList<String?> = LinkedList()
|
||||
val units = profileFunction.getUnits()
|
||||
val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
|
||||
val unitLabel = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl)
|
||||
val recordOnlyChecked = binding.recordOnly.isChecked
|
||||
val eatingSoonChecked = binding.startEatingSoonTt.isChecked
|
||||
|
||||
if (insulinAfterConstraints > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, resourceHelper).formatColor(resourceHelper, R.color.bolus))
|
||||
actions.add(rh.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, rh).formatColor(rh, R.color.bolus))
|
||||
if (recordOnlyChecked)
|
||||
actions.add(resourceHelper.gs(R.string.bolusrecordedonly).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.bolusrecordedonly).formatColor(rh, R.color.warning))
|
||||
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(rh, R.color.warning))
|
||||
}
|
||||
val eatingSoonTTDuration = defaultValueHelper.determineEatingSoonTTDuration()
|
||||
val eatingSoonTT = defaultValueHelper.determineEatingSoonTT()
|
||||
if (eatingSoonChecked)
|
||||
actions.add(resourceHelper.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + resourceHelper.gs(R.string.format_mins, eatingSoonTTDuration) + ")").formatColor(resourceHelper, R.color.tempTargetConfirmation))
|
||||
actions.add(rh.gs(R.string.temptargetshort) + ": " + (DecimalFormatter.to1Decimal(eatingSoonTT) + " " + unitLabel + " (" + rh.gs(R.string.format_mins, eatingSoonTTDuration) + ")").formatColor(rh, R.color.tempTargetConfirmation))
|
||||
|
||||
val timeOffset = binding.time.value.toInt()
|
||||
val time = DateUtil.now() + T.mins(timeOffset.toLong()).msecs()
|
||||
val time = dateUtil.now() + T.mins(timeOffset.toLong()).msecs()
|
||||
if (timeOffset != 0)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time))
|
||||
actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time))
|
||||
|
||||
val notes = binding.notesLayout.notes.text.toString()
|
||||
if (notes.isNotEmpty())
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||
actions.add(rh.gs(R.string.notes_label) + ": " + notes)
|
||||
|
||||
if (insulinAfterConstraints > 0 || eatingSoonChecked) {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.bolus), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
if (eatingSoonChecked) {
|
||||
aapsLogger.debug("USER ENTRY: TEMPTARGET EATING SOON $eatingSoonTT duration: $eatingSoonTTDuration")
|
||||
val tempTarget = TempTarget()
|
||||
.date(System.currentTimeMillis())
|
||||
.duration(eatingSoonTTDuration)
|
||||
.reason(resourceHelper.gs(R.string.eatingsoon))
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()))
|
||||
.high(Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()))
|
||||
activePlugin.activeTreatments.addToHistoryTempTarget(tempTarget)
|
||||
uel.log(Action.TT, Sources.InsulinDialog,
|
||||
notes,
|
||||
ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON),
|
||||
ValueWithUnit.fromGlucoseUnit(eatingSoonTT, units.asText),
|
||||
ValueWithUnit.Minute(eatingSoonTTDuration))
|
||||
disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = System.currentTimeMillis(),
|
||||
duration = TimeUnit.MINUTES.toMillis(eatingSoonTTDuration.toLong()),
|
||||
reason = TemporaryTarget.Reason.EATING_SOON,
|
||||
lowTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(eatingSoonTT, profileFunction.getUnits())
|
||||
)).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
}
|
||||
if (insulinAfterConstraints > 0) {
|
||||
val detailedBolusInfo = DetailedBolusInfo()
|
||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
|
||||
detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS
|
||||
detailedBolusInfo.insulin = insulinAfterConstraints
|
||||
detailedBolusInfo.context = context
|
||||
detailedBolusInfo.source = Source.USER
|
||||
detailedBolusInfo.notes = notes
|
||||
detailedBolusInfo.timestamp = time
|
||||
if (recordOnlyChecked) {
|
||||
aapsLogger.debug("USER ENTRY: BOLUS RECORD ONLY $insulinAfterConstraints")
|
||||
detailedBolusInfo.date = time
|
||||
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
|
||||
uel.log(Action.BOLUS, Sources.InsulinDialog,
|
||||
rh.gs(R.string.record) + if (notes.isNotEmpty()) ": " + notes else "",
|
||||
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.record)),
|
||||
ValueWithUnit.Insulin(insulinAfterConstraints),
|
||||
ValueWithUnit.Minute(timeOffset).takeIf { timeOffset!= 0 })
|
||||
disposable += repository.runTransactionForResult(detailedBolusInfo.insertBolusTransaction())
|
||||
.subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it) }
|
||||
)
|
||||
if (timeOffset == 0)
|
||||
bolusTimer.removeBolusReminder()
|
||||
} else {
|
||||
aapsLogger.debug("USER ENTRY: BOLUS $insulinAfterConstraints")
|
||||
detailedBolusInfo.date = DateUtil.now()
|
||||
uel.log(Action.BOLUS, Sources.InsulinDialog,
|
||||
notes,
|
||||
ValueWithUnit.Insulin(insulinAfterConstraints))
|
||||
commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror)
|
||||
} else {
|
||||
bolusTimer.removeBolusReminder()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -217,7 +240,7 @@ class InsulinDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
} else
|
||||
activity?.let { activity ->
|
||||
OKDialog.show(activity, resourceHelper.gs(R.string.bolus), resourceHelper.gs(R.string.no_action_selected))
|
||||
OKDialog.show(activity, rh.gs(R.string.bolus), rh.gs(R.string.no_action_selected))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.HandlerThread
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -13,22 +13,35 @@ import androidx.fragment.app.FragmentManager
|
|||
import dagger.android.support.DaggerDialogFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.OfflineEvent
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.CancelCurrentOfflineEventIfAnyTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentOfflineEventTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogLoopBinding
|
||||
import info.nightscout.androidaps.events.*
|
||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||
import info.nightscout.androidaps.extensions.runOnUiThread
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
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.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoopDialog : DaggerDialogFragment() {
|
||||
|
@ -36,28 +49,37 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var objectivesPlugin: ObjectivesPlugin
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var loop: Loop
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var configBuilder: ConfigBuilder
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var objectivePlugin: ObjectivesPlugin
|
||||
|
||||
private var showOkCancel: Boolean = true
|
||||
private var _binding: DialogLoopBinding? = null
|
||||
private var loopHandler = Handler()
|
||||
private var refreshDialog: Runnable? = null
|
||||
private var handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper)
|
||||
private lateinit var refreshDialog: Runnable
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
val disposable = CompositeDisposable()
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
dialog?.window?.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
|
@ -65,8 +87,10 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
savedInstanceState.putInt("showOkCancel", if (showOkCancel) 1 else 0)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
// load data from bundle
|
||||
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||
showOkCancel = bundle.getInt("showOkCancel", 1) == 1
|
||||
|
@ -104,55 +128,97 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
binding.cancel.setOnClickListener { dismiss() }
|
||||
|
||||
refreshDialog = Runnable {
|
||||
scheduleUpdateGUI("refreshDialog")
|
||||
loopHandler.postDelayed(refreshDialog, 15 * 1000L)
|
||||
runOnUiThread { updateGUI("refreshDialog") }
|
||||
handler.postDelayed(refreshDialog, 15 * 1000L)
|
||||
}
|
||||
loopHandler.postDelayed(refreshDialog, 15 * 1000L)
|
||||
handler.postDelayed(refreshDialog, 15 * 1000L)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
loopHandler.removeCallbacksAndMessages(null)
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
var task: Runnable? = null
|
||||
|
||||
private fun scheduleUpdateGUI(from: String) {
|
||||
class UpdateRunnable : Runnable {
|
||||
|
||||
override fun run() {
|
||||
updateGUI(from)
|
||||
task = null
|
||||
}
|
||||
}
|
||||
view?.removeCallbacks(task)
|
||||
task = UpdateRunnable()
|
||||
view?.postDelayed(task, 500)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateGUI(from: String) {
|
||||
if (_binding == null) return
|
||||
aapsLogger.debug("UpdateGUI from $from")
|
||||
val pumpDescription: PumpDescription = activePlugin.activePump.pumpDescription
|
||||
val closedLoopAllowed = objectivesPlugin.isClosedLoopAllowed(Constraint(true))
|
||||
val lgsEnabled = objectivesPlugin.isLgsAllowed(Constraint(true))
|
||||
val closedLoopAllowed = constraintChecker.isClosedLoopAllowed(Constraint(true))
|
||||
val closedLoopAllowed2 = objectivePlugin.objectives[ObjectivesPlugin.MAXIOB_OBJECTIVE].isCompleted
|
||||
val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true))
|
||||
val apsMode = sp.getString(R.string.key_aps_mode, "open")
|
||||
if (profileFunction.isProfileValid("LoopDialogUpdateGUI")) {
|
||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||
val pump = activePlugin.activePump
|
||||
|
||||
binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility()
|
||||
binding.overviewDisconnect30m.visibility = pumpDescription.tempDurationStep30mAllowed.toVisibility()
|
||||
when {
|
||||
closedLoopAllowed.value() -> {
|
||||
binding.overviewCloseloop.visibility = (apsMode != "closed").toVisibility()
|
||||
binding.overviewLgsloop.visibility = (apsMode != "lgs").toVisibility()
|
||||
binding.overviewOpenloop.visibility = (apsMode != "open").toVisibility()
|
||||
pump.isSuspended() -> {
|
||||
binding.overviewLoop.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
binding.overviewPump.visibility = View.GONE
|
||||
}
|
||||
|
||||
lgsEnabled.value() -> {
|
||||
!profileFunction.isProfileValid("LoopDialogUpdateGUI") -> {
|
||||
binding.overviewLoop.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
binding.overviewPump.visibility = View.GONE
|
||||
}
|
||||
|
||||
loop.isDisconnected -> {
|
||||
binding.overviewLoop.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
binding.overviewPump.visibility = View.VISIBLE
|
||||
binding.overviewPumpHeader.text = rh.gs(R.string.reconnect)
|
||||
binding.overviewDisconnectButtons.visibility = View.VISIBLE
|
||||
binding.overviewReconnect.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
!(loop as PluginBase).isEnabled() -> {
|
||||
binding.overviewLoop.visibility = View.VISIBLE
|
||||
binding.overviewEnable.visibility = View.VISIBLE
|
||||
binding.overviewDisable.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
binding.overviewPump.visibility = View.VISIBLE
|
||||
binding.overviewReconnect.visibility = View.GONE
|
||||
}
|
||||
|
||||
loop.isSuspended -> {
|
||||
binding.overviewLoop.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.VISIBLE
|
||||
binding.overviewSuspendHeader.text = rh.gs(R.string.resumeloop)
|
||||
binding.overviewSuspendButtons.visibility = View.VISIBLE
|
||||
binding.overviewResume.visibility = View.VISIBLE
|
||||
binding.overviewPump.visibility = View.GONE
|
||||
binding.overviewReconnect.visibility = View.GONE
|
||||
}
|
||||
|
||||
else -> {
|
||||
binding.overviewLoop.visibility = View.VISIBLE
|
||||
binding.overviewEnable.visibility = View.GONE
|
||||
when {
|
||||
apsMode == "closed" -> {
|
||||
binding.overviewCloseloop.visibility = View.GONE
|
||||
binding.overviewLgsloop.visibility = (apsMode != "lgs").toVisibility()
|
||||
binding.overviewOpenloop.visibility = (apsMode != "open").toVisibility()
|
||||
binding.overviewLgsloop.visibility = View.VISIBLE
|
||||
binding.overviewOpenloop.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
apsMode == "lgs" -> {
|
||||
binding.overviewCloseloop.visibility = closedLoopAllowed.value().toVisibility() //show Close loop button only if Close loop allowed
|
||||
binding.overviewLgsloop.visibility = View.GONE
|
||||
binding.overviewOpenloop.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
apsMode == "open" -> {
|
||||
binding.overviewCloseloop.visibility =
|
||||
closedLoopAllowed2.toVisibility() //show CloseLoop button only if Objective 6 is completed (closedLoopAllowed always false in open loop mode)
|
||||
binding.overviewLgsloop.visibility = lgsEnabled.value().toVisibility()
|
||||
binding.overviewOpenloop.visibility = View.GONE
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
@ -161,72 +227,42 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
binding.overviewOpenloop.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
binding.overviewEnable.visibility = View.GONE
|
||||
binding.overviewDisable.visibility = View.VISIBLE
|
||||
if (!loopPlugin.isSuspended) {
|
||||
binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.suspendloop)
|
||||
binding.overviewResume.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.VISIBLE
|
||||
binding.overviewSuspendHeader.text = rh.gs(R.string.suspendloop)
|
||||
binding.overviewSuspendButtons.visibility = View.VISIBLE
|
||||
binding.overviewSuspend.visibility = View.VISIBLE
|
||||
} else {
|
||||
if (!loopPlugin.isDisconnected) {
|
||||
binding.overviewSuspendHeader.text = resourceHelper.gs(R.string.resumeloop)
|
||||
binding.overviewResume.visibility = View.VISIBLE
|
||||
binding.overviewSuspendButtons.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.VISIBLE
|
||||
} else
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
}
|
||||
} else {
|
||||
binding.overviewEnable.visibility = View.VISIBLE
|
||||
binding.overviewDisable.visibility = View.GONE
|
||||
binding.overviewSuspend.visibility = View.GONE
|
||||
}
|
||||
if (!loopPlugin.isDisconnected) {
|
||||
binding.overviewPumpHeader.text = resourceHelper.gs(R.string.disconnectpump)
|
||||
binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility()
|
||||
binding.overviewDisconnect30m.visibility = pumpDescription.tempDurationStep30mAllowed.toVisibility()
|
||||
binding.overviewResume.visibility = View.GONE
|
||||
|
||||
binding.overviewPump.visibility = View.VISIBLE
|
||||
binding.overviewPumpHeader.text = rh.gs(R.string.disconnectpump)
|
||||
binding.overviewDisconnectButtons.visibility = View.VISIBLE
|
||||
binding.overviewReconnect.visibility = View.GONE
|
||||
} else {
|
||||
binding.overviewPumpHeader.text = resourceHelper.gs(R.string.reconnect)
|
||||
binding.overviewDisconnectButtons.visibility = View.GONE
|
||||
binding.overviewReconnect.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
val profile = profileFunction.getProfile()
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
|
||||
if (profile == null || profileStore == null) {
|
||||
ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.noprofile))
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private fun onClickOkCancelEnabled(v: View): Boolean {
|
||||
var description = ""
|
||||
when (v.id) {
|
||||
R.id.overview_closeloop -> description = resourceHelper.gs(R.string.closedloop)
|
||||
R.id.overview_lgsloop -> description = resourceHelper.gs(R.string.lowglucosesuspend)
|
||||
R.id.overview_openloop -> description = resourceHelper.gs(R.string.openloop)
|
||||
R.id.overview_disable -> description = resourceHelper.gs(R.string.disableloop)
|
||||
R.id.overview_enable -> description = resourceHelper.gs(R.string.enableloop)
|
||||
R.id.overview_resume -> description = resourceHelper.gs(R.string.resume)
|
||||
R.id.overview_reconnect -> description = resourceHelper.gs(R.string.reconnect)
|
||||
R.id.overview_suspend_1h -> description = resourceHelper.gs(R.string.suspendloopfor1h)
|
||||
R.id.overview_suspend_2h -> description = resourceHelper.gs(R.string.suspendloopfor2h)
|
||||
R.id.overview_suspend_3h -> description = resourceHelper.gs(R.string.suspendloopfor3h)
|
||||
R.id.overview_suspend_10h -> description = resourceHelper.gs(R.string.suspendloopfor10h)
|
||||
R.id.overview_disconnect_15m -> description = resourceHelper.gs(R.string.disconnectpumpfor15m)
|
||||
R.id.overview_disconnect_30m -> description = resourceHelper.gs(R.string.disconnectpumpfor30m)
|
||||
R.id.overview_disconnect_1h -> description = resourceHelper.gs(R.string.disconnectpumpfor1h)
|
||||
R.id.overview_disconnect_2h -> description = resourceHelper.gs(R.string.disconnectpumpfor2h)
|
||||
R.id.overview_disconnect_3h -> description = resourceHelper.gs(R.string.disconnectpumpfor3h)
|
||||
R.id.overview_closeloop -> description = rh.gs(R.string.closedloop)
|
||||
R.id.overview_lgsloop -> description = rh.gs(R.string.lowglucosesuspend)
|
||||
R.id.overview_openloop -> description = rh.gs(R.string.openloop)
|
||||
R.id.overview_disable -> description = rh.gs(R.string.disableloop)
|
||||
R.id.overview_enable -> description = rh.gs(R.string.enableloop)
|
||||
R.id.overview_resume -> description = rh.gs(R.string.resume)
|
||||
R.id.overview_reconnect -> description = rh.gs(R.string.reconnect)
|
||||
R.id.overview_suspend_1h -> description = rh.gs(R.string.suspendloopfor1h)
|
||||
R.id.overview_suspend_2h -> description = rh.gs(R.string.suspendloopfor2h)
|
||||
R.id.overview_suspend_3h -> description = rh.gs(R.string.suspendloopfor3h)
|
||||
R.id.overview_suspend_10h -> description = rh.gs(R.string.suspendloopfor10h)
|
||||
R.id.overview_disconnect_15m -> description = rh.gs(R.string.disconnectpumpfor15m)
|
||||
R.id.overview_disconnect_30m -> description = rh.gs(R.string.disconnectpumpfor30m)
|
||||
R.id.overview_disconnect_1h -> description = rh.gs(R.string.disconnectpumpfor1h)
|
||||
R.id.overview_disconnect_2h -> description = rh.gs(R.string.disconnectpumpfor2h)
|
||||
R.id.overview_disconnect_3h -> description = rh.gs(R.string.disconnectpumpfor3h)
|
||||
}
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.confirm), description, Runnable {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.confirm), description, Runnable {
|
||||
onClick(v)
|
||||
})
|
||||
}
|
||||
|
@ -234,138 +270,157 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
}
|
||||
|
||||
fun onClick(v: View): Boolean {
|
||||
val profile = profileFunction.getProfile() ?: return true
|
||||
when (v.id) {
|
||||
R.id.overview_closeloop -> {
|
||||
aapsLogger.debug("USER ENTRY: CLOSED LOOP MODE")
|
||||
uel.log(Action.CLOSED_LOOP_MODE, Sources.LoopDialog)
|
||||
sp.putString(R.string.key_aps_mode, "closed")
|
||||
rxBus.send(EventPreferenceChange(resourceHelper.gs(R.string.closedloop)))
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.closedloop)))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_lgsloop -> {
|
||||
aapsLogger.debug("USER ENTRY: LGS LOOP MODE")
|
||||
uel.log(Action.LGS_LOOP_MODE, Sources.LoopDialog)
|
||||
sp.putString(R.string.key_aps_mode, "lgs")
|
||||
rxBus.send(EventPreferenceChange(resourceHelper.gs(R.string.lowglucosesuspend)))
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.lowglucosesuspend)))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_openloop -> {
|
||||
aapsLogger.debug("USER ENTRY: OPEN LOOP MODE")
|
||||
uel.log(Action.OPEN_LOOP_MODE, Sources.LoopDialog)
|
||||
sp.putString(R.string.key_aps_mode, "open")
|
||||
rxBus.send(EventPreferenceChange(resourceHelper.gs(R.string.lowglucosesuspend)))
|
||||
rxBus.send(EventPreferenceChange(rh.gs(R.string.lowglucosesuspend)))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disable -> {
|
||||
aapsLogger.debug("USER ENTRY: LOOP DISABLED")
|
||||
loopPlugin.setPluginEnabled(PluginType.LOOP, false)
|
||||
loopPlugin.setFragmentVisible(PluginType.LOOP, false)
|
||||
configBuilderPlugin.storeSettings("DisablingLoop")
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(Action.LOOP_DISABLED, Sources.LoopDialog)
|
||||
(loop as PluginBase).setPluginEnabled(PluginType.LOOP, false)
|
||||
(loop as PluginBase).setFragmentVisible(PluginType.LOOP, false)
|
||||
configBuilder.storeSettings("DisablingLoop")
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
commandQueue.cancelTempBasal(true, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
ToastUtils.showToastInUiThread(ctx, resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.tempbasaldeliveryerror))
|
||||
}
|
||||
}
|
||||
})
|
||||
loopPlugin.createOfflineEvent(24 * 60) // upload 24h, we don't know real duration
|
||||
disposable += repository.runTransactionForResult(InsertAndCancelCurrentOfflineEventTransaction(dateUtil.now(), T.days(365).msecs(), OfflineEvent.Reason.DISABLE_LOOP))
|
||||
.subscribe({ result ->
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted OfflineEvent $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_enable -> {
|
||||
aapsLogger.debug("USER ENTRY: LOOP ENABLED")
|
||||
loopPlugin.setPluginEnabled(PluginType.LOOP, true)
|
||||
loopPlugin.setFragmentVisible(PluginType.LOOP, true)
|
||||
configBuilderPlugin.storeSettings("EnablingLoop")
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
loopPlugin.createOfflineEvent(0)
|
||||
uel.log(Action.LOOP_ENABLED, Sources.LoopDialog)
|
||||
(loop as PluginBase).setPluginEnabled(PluginType.LOOP, true)
|
||||
(loop as PluginBase).setFragmentVisible(PluginType.LOOP, true)
|
||||
configBuilder.storeSettings("EnablingLoop")
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
disposable += repository.runTransactionForResult(CancelCurrentOfflineEventIfAnyTransaction(dateUtil.now()))
|
||||
.subscribe({ result ->
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_resume, R.id.overview_reconnect -> {
|
||||
aapsLogger.debug("USER ENTRY: RESUME")
|
||||
loopPlugin.suspendTo(0L)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(if (v.id == R.id.overview_resume) Action.RESUME else Action.RECONNECT, Sources.LoopDialog)
|
||||
disposable += repository.runTransactionForResult(CancelCurrentOfflineEventIfAnyTransaction(dateUtil.now()))
|
||||
.subscribe({ result ->
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated OfflineEvent $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving OfflineEvent", it)
|
||||
})
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
commandQueue.cancelTempBasal(true, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror)
|
||||
}
|
||||
}
|
||||
})
|
||||
sp.putBoolean(R.string.key_objectiveusereconnect, true)
|
||||
loopPlugin.createOfflineEvent(0)
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_suspend_1h -> {
|
||||
aapsLogger.debug("USER ENTRY: SUSPEND 1h")
|
||||
loopPlugin.suspendLoop(60)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(Action.SUSPEND, Sources.LoopDialog, ValueWithUnit.Hour(1))
|
||||
loop.suspendLoop(T.hours(1).mins().toInt())
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_suspend_2h -> {
|
||||
aapsLogger.debug("USER ENTRY: SUSPEND 2h")
|
||||
loopPlugin.suspendLoop(120)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(Action.SUSPEND, Sources.LoopDialog, ValueWithUnit.Hour(2))
|
||||
loop.suspendLoop(T.hours(2).mins().toInt())
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_suspend_3h -> {
|
||||
aapsLogger.debug("USER ENTRY: SUSPEND 3h")
|
||||
loopPlugin.suspendLoop(180)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(Action.SUSPEND, Sources.LoopDialog, ValueWithUnit.Hour(3))
|
||||
loop.suspendLoop(T.hours(3).mins().toInt())
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_suspend_10h -> {
|
||||
aapsLogger.debug("USER ENTRY: SUSPEND 10h")
|
||||
loopPlugin.suspendLoop(600)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
uel.log(Action.SUSPEND, Sources.LoopDialog, ValueWithUnit.Hour(10))
|
||||
loop.suspendLoop(T.hours(10).mins().toInt())
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disconnect_15m -> {
|
||||
aapsLogger.debug("USER ENTRY: DISCONNECT 15m")
|
||||
loopPlugin.disconnectPump(15, profile)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
uel.log(Action.DISCONNECT, Sources.LoopDialog, ValueWithUnit.Minute(15))
|
||||
loop.goToZeroTemp(T.mins(15).mins().toInt(), profile, OfflineEvent.Reason.DISCONNECT_PUMP)
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disconnect_30m -> {
|
||||
aapsLogger.debug("USER ENTRY: DISCONNECT 30m")
|
||||
loopPlugin.disconnectPump(30, profile)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
uel.log(Action.DISCONNECT, Sources.LoopDialog, ValueWithUnit.Minute(30))
|
||||
loop.goToZeroTemp(T.mins(30).mins().toInt(), profile, OfflineEvent.Reason.DISCONNECT_PUMP)
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disconnect_1h -> {
|
||||
aapsLogger.debug("USER ENTRY: DISCONNECT 1h")
|
||||
loopPlugin.disconnectPump(60, profile)
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
uel.log(Action.DISCONNECT, Sources.LoopDialog, ValueWithUnit.Hour(1))
|
||||
loop.goToZeroTemp(T.hours(1).mins().toInt(), profile, OfflineEvent.Reason.DISCONNECT_PUMP)
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
}
|
||||
sp.putBoolean(R.string.key_objectiveusedisconnect, true)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disconnect_2h -> {
|
||||
aapsLogger.debug("USER ENTRY: DISCONNECT 2h")
|
||||
loopPlugin.disconnectPump(120, profile)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
uel.log(Action.DISCONNECT, Sources.LoopDialog, ValueWithUnit.Hour(2))
|
||||
loop.goToZeroTemp(T.hours(2).mins().toInt(), profile, OfflineEvent.Reason.DISCONNECT_PUMP)
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
R.id.overview_disconnect_3h -> {
|
||||
aapsLogger.debug("USER ENTRY: DISCONNECT 3h")
|
||||
loopPlugin.disconnectPump(180, profile)
|
||||
rxBus.send(EventRefreshOverview("suspendmenu"))
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
uel.log(Action.DISCONNECT, Sources.LoopDialog, ValueWithUnit.Hour(3))
|
||||
loop.goToZeroTemp(T.hours(3).mins().toInt(), profile, OfflineEvent.Reason.DISCONNECT_PUMP)
|
||||
rxBus.send(EventRefreshOverview("suspend_menu"))
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -379,7 +434,7 @@ class LoopDialog : DaggerDialogFragment() {
|
|||
it.commitAllowingStateLoss()
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
aapsLogger.debug(e.localizedMessage)
|
||||
aapsLogger.debug(e.localizedMessage ?: e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -8,33 +10,69 @@ import android.widget.ArrayAdapter
|
|||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogProfileswitchBinding
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
class ProfileSwitchDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var hardLimits: HardLimits
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
|
||||
private var profileIndex: Int? = null
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var _binding: DialogProfileswitchBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
val isDuration = binding.duration.value > 0
|
||||
val isLowerPercentage = binding.percentage.value < 100
|
||||
binding.ttLayout.visibility = (isDuration && isLowerPercentage).toVisibility()
|
||||
}
|
||||
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putDouble("duration", binding.duration.value)
|
||||
|
@ -42,8 +80,10 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
|
|||
savedInstanceState.putDouble("timeshift", binding.timeshift.value)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
onCreateViewGeneral()
|
||||
arguments?.let { bundle ->
|
||||
profileIndex = bundle.getInt("profileIndex", 0)
|
||||
|
@ -55,18 +95,36 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.duration.setParams(savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
binding.percentage.setParams(savedInstanceState?.getDouble("percentage")
|
||||
?: 100.0, Constants.CPP_MIN_PERCENTAGE.toDouble(), Constants.CPP_MAX_PERCENTAGE.toDouble(), 5.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
binding.timeshift.setParams(savedInstanceState?.getDouble("timeshift")
|
||||
?: 0.0, Constants.CPP_MIN_TIMESHIFT.toDouble(), Constants.CPP_MAX_TIMESHIFT.toDouble(), 1.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
binding.duration.setParams(
|
||||
savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, binding.okcancel.ok,
|
||||
textWatcher
|
||||
)
|
||||
binding.percentage.setParams(
|
||||
savedInstanceState?.getDouble("percentage")
|
||||
?: 100.0, Constants.CPP_MIN_PERCENTAGE.toDouble(), Constants.CPP_MAX_PERCENTAGE.toDouble(), 5.0,
|
||||
DecimalFormat("0"), false, binding.okcancel.ok, textWatcher
|
||||
)
|
||||
binding.timeshift.setParams(
|
||||
savedInstanceState?.getDouble("timeshift")
|
||||
?: 0.0, Constants.CPP_MIN_TIMESHIFT.toDouble(), Constants.CPP_MAX_TIMESHIFT.toDouble(), 1.0, DecimalFormat("0"), false, binding.okcancel.ok
|
||||
)
|
||||
|
||||
// profile
|
||||
context?.let { context ->
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
?: return
|
||||
val profileList = profileStore.getProfileList()
|
||||
val profileListToCheck = profileStore.getProfileList()
|
||||
val profileList = ArrayList<CharSequence>()
|
||||
for (profileName in profileListToCheck) {
|
||||
val profileToCheck = activePlugin.activeProfileSource.profile?.getSpecificProfile(profileName.toString())
|
||||
if (profileToCheck != null && ProfileSealed.Pure(profileToCheck).isValid("ProfileSwitch", activePlugin.activePump, config, rh, rxBus, hardLimits, false).isValid)
|
||||
profileList.add(profileName)
|
||||
}
|
||||
if (profileList.isEmpty()) {
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
binding.profile.adapter = adapter
|
||||
// set selected to actual profile
|
||||
|
@ -74,57 +132,113 @@ class ProfileSwitchDialog : DialogFragmentWithDate() {
|
|||
binding.profile.setSelection(profileIndex as Int)
|
||||
else
|
||||
for (p in profileList.indices)
|
||||
if (profileList[p] == profileFunction.getProfileName(false))
|
||||
if (profileList[p] == profileFunction.getOriginalProfileName())
|
||||
binding.profile.setSelection(p)
|
||||
} ?: return
|
||||
}
|
||||
|
||||
treatmentsPlugin.getProfileSwitchFromHistory(DateUtil.now())?.let { ps ->
|
||||
if (ps.isCPP) {
|
||||
profileFunction.getProfile()?.let { profile ->
|
||||
if (profile is ProfileSealed.EPS)
|
||||
if (profile.value.originalPercentage != 100 || profile.value.originalTimeshift != 0L) {
|
||||
binding.reuselayout.visibility = View.VISIBLE
|
||||
binding.reusebutton.text = resourceHelper.gs(R.string.reuse_profile_pct_hours, ps.percentage, ps.timeshift)
|
||||
binding.reusebutton.text = rh.gs(R.string.reuse_profile_pct_hours, profile.value.originalPercentage, T.msecs(profile.value.originalTimeshift).hours().toInt())
|
||||
binding.reusebutton.setOnClickListener {
|
||||
binding.percentage.value = ps.percentage.toDouble()
|
||||
binding.timeshift.value = ps.timeshift.toDouble()
|
||||
}
|
||||
} else {
|
||||
binding.reuselayout.visibility = View.GONE
|
||||
binding.percentage.value = profile.value.originalPercentage.toDouble()
|
||||
binding.timeshift.value = profile.value.originalTimeshift.toDouble()
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.ttLayout.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
?: return false
|
||||
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
val duration = binding.duration.value?.toInt() ?: return false
|
||||
if (duration > 0)
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, duration))
|
||||
val profile = binding.profile.selectedItem.toString()
|
||||
actions.add(resourceHelper.gs(R.string.profile) + ": " + profile)
|
||||
val duration = binding.duration.value.toInt()
|
||||
if (duration > 0L)
|
||||
actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, duration))
|
||||
val profileName = binding.profile.selectedItem.toString()
|
||||
actions.add(rh.gs(R.string.profile) + ": " + profileName)
|
||||
val percent = binding.percentage.value.toInt()
|
||||
if (percent != 100)
|
||||
actions.add(resourceHelper.gs(R.string.percent) + ": " + percent + "%")
|
||||
actions.add(rh.gs(R.string.percent) + ": " + percent + "%")
|
||||
val timeShift = binding.timeshift.value.toInt()
|
||||
if (timeShift != 0)
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_timeshift_label) + ": " + resourceHelper.gs(R.string.format_hours, timeShift.toDouble()))
|
||||
actions.add(rh.gs(R.string.careportal_newnstreatment_timeshift_label) + ": " + rh.gs(R.string.format_hours, timeShift.toDouble()))
|
||||
val notes = binding.notesLayout.notes.text.toString()
|
||||
if (notes.isNotEmpty())
|
||||
actions.add(resourceHelper.gs(R.string.careportal_newnstreatment_notes_label) + ": " + notes)
|
||||
actions.add(rh.gs(R.string.notes_label) + ": " + notes)
|
||||
if (eventTimeChanged)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
|
||||
val isTT = binding.duration.value > 0 && binding.percentage.value < 100 && binding.tt.isChecked
|
||||
val target = defaultValueHelper.determineActivityTT()
|
||||
val units = profileFunction.getUnits()
|
||||
if (isTT)
|
||||
actions.add(rh.gs(R.string.careportal_temporarytarget) + ": " + rh.gs(R.string.activity))
|
||||
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
aapsLogger.debug("USER ENTRY: PROFILE SWITCH $profile percent: $percent timeshift: $timeShift duration: $duration")
|
||||
treatmentsPlugin.doProfileSwitch(profileStore, profile, duration, percent, timeShift, eventTime)
|
||||
val ps = profileFunction.buildProfileSwitch(profileStore, profileName, duration, percent, timeShift, eventTime) ?: return@let
|
||||
val validity = ProfileSealed.PS(ps).isValid(rh.gs(R.string.careportal_profileswitch), activePlugin.activePump, config, rh, rxBus, hardLimits, false)
|
||||
if (validity.isValid)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal_profileswitch), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
if (profileFunction.createProfileSwitch(
|
||||
profileStore,
|
||||
profileName = profileName,
|
||||
durationInMinutes = duration,
|
||||
percentage = percent,
|
||||
timeShiftInHours = timeShift,
|
||||
timestamp = eventTime
|
||||
)
|
||||
) {
|
||||
uel.log(Action.PROFILE_SWITCH,
|
||||
Sources.ProfileSwitchDialog,
|
||||
notes,
|
||||
ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged },
|
||||
ValueWithUnit.SimpleString(profileName),
|
||||
ValueWithUnit.Percent(percent),
|
||||
ValueWithUnit.Hour(timeShift).takeIf { timeShift != 0 },
|
||||
ValueWithUnit.Minute(duration).takeIf { duration != 0 })
|
||||
if (percent == 90 && duration == 10) sp.putBoolean(R.string.key_objectiveuseprofileswitch, true)
|
||||
if (isTT) {
|
||||
disposable += repository.runTransactionForResult(
|
||||
InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = eventTime,
|
||||
duration = TimeUnit.MINUTES.toMillis(duration.toLong()),
|
||||
reason = TemporaryTarget.Reason.ACTIVITY,
|
||||
lowTarget = Profile.toMgdl(target, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(target, profileFunction.getUnits())
|
||||
)
|
||||
).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
uel.log(
|
||||
Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(
|
||||
TemporaryTarget.Reason.ACTIVITY
|
||||
), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration)
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
else {
|
||||
OKDialog.show(
|
||||
activity,
|
||||
rh.gs(R.string.careportal_profileswitch),
|
||||
HtmlHelper.fromHtml(Joiner.on("<br/>").join(validity.reasons))
|
||||
)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
|
@ -9,18 +8,18 @@ import android.view.ViewGroup
|
|||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.DialogTempbasalBinding
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
@ -30,11 +29,12 @@ import kotlin.math.abs
|
|||
class TempBasalDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
|
||||
private var isPercentPump = true
|
||||
|
||||
|
@ -47,8 +47,8 @@ class TempBasalDialog : DialogFragmentWithDate() {
|
|||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putDouble("duration", binding.duration.value)
|
||||
savedInstanceState.putDouble("basalpercentinput", binding.basalpercentinput.value)
|
||||
savedInstanceState.putDouble("basalabsoluteinput", binding.basalabsoluteinput.value)
|
||||
savedInstanceState.putDouble("basalPercentInput", binding.basalPercentInput.value)
|
||||
savedInstanceState.putDouble("basalAbsoluteInput", binding.basalAbsoluteInput.value)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -67,11 +67,11 @@ class TempBasalDialog : DialogFragmentWithDate() {
|
|||
val maxTempPercent = pumpDescription.maxTempPercent.toDouble()
|
||||
val tempPercentStep = pumpDescription.tempPercentStep.toDouble()
|
||||
|
||||
binding.basalpercentinput.setParams(savedInstanceState?.getDouble("basalpercentinput")
|
||||
binding.basalPercentInput.setParams(savedInstanceState?.getDouble("basalPercentInput")
|
||||
?: 100.0, 0.0, maxTempPercent, tempPercentStep, DecimalFormat("0"), true, binding.okcancel.ok)
|
||||
|
||||
binding.basalabsoluteinput.setParams(savedInstanceState?.getDouble("basalabsoluteinput")
|
||||
?: profile.basal, 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, binding.okcancel.ok)
|
||||
binding.basalAbsoluteInput.setParams(savedInstanceState?.getDouble("basalAbsoluteInput")
|
||||
?: profile.getBasal(), 0.0, pumpDescription.maxTempAbsolute, pumpDescription.tempAbsoluteStep, DecimalFormat("0.00"), true, binding.okcancel.ok)
|
||||
|
||||
val tempDurationStep = pumpDescription.tempDurationStep.toDouble()
|
||||
val tempMaxDuration = pumpDescription.tempMaxDuration.toDouble()
|
||||
|
@ -97,43 +97,42 @@ class TempBasalDialog : DialogFragmentWithDate() {
|
|||
if (_binding == null) return false
|
||||
var percent = 0
|
||||
var absolute = 0.0
|
||||
val durationInMinutes = binding.duration.value?.toInt() ?: return false
|
||||
val durationInMinutes = binding.duration.value.toInt()
|
||||
val profile = profileFunction.getProfile() ?: return false
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
if (isPercentPump) {
|
||||
val basalPercentInput = SafeParse.stringToInt(binding.basalpercentinput.text)
|
||||
val basalPercentInput = SafeParse.stringToInt(binding.basalPercentInput.text)
|
||||
percent = constraintChecker.applyBasalPercentConstraints(Constraint(basalPercentInput), profile).value()
|
||||
actions.add(resourceHelper.gs(R.string.tempbasal_label) + ": $percent%")
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, durationInMinutes))
|
||||
if (percent != basalPercentInput) actions.add(resourceHelper.gs(R.string.constraintapllied))
|
||||
actions.add(rh.gs(R.string.tempbasal_label) + ": $percent%")
|
||||
actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes))
|
||||
if (percent != basalPercentInput) actions.add(rh.gs(R.string.constraintapllied))
|
||||
} else {
|
||||
val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalabsoluteinput.text)
|
||||
val basalAbsoluteInput = SafeParse.stringToDouble(binding.basalAbsoluteInput.text)
|
||||
absolute = constraintChecker.applyBasalConstraints(Constraint(basalAbsoluteInput), profile).value()
|
||||
actions.add(resourceHelper.gs(R.string.tempbasal_label) + ": " + resourceHelper.gs(R.string.pump_basebasalrate, absolute))
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, durationInMinutes))
|
||||
actions.add(rh.gs(R.string.tempbasal_label) + ": " + rh.gs(R.string.pump_basebasalrate, absolute))
|
||||
actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, durationInMinutes))
|
||||
if (abs(absolute - basalAbsoluteInput) > 0.01)
|
||||
actions.add(resourceHelper.gs(R.string.constraintapllied).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.constraintapllied).formatColor(rh, R.color.warning))
|
||||
}
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.tempbasal_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.tempbasal_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
val callback: Callback = object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.tempbasaldeliveryerror), R.raw.boluserror)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isPercentPump) {
|
||||
aapsLogger.debug("USER ENTRY: TEMP BASAL $percent% duration: $durationInMinutes")
|
||||
commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, callback)
|
||||
uel.log(Action.TEMP_BASAL, Sources.TempBasalDialog,
|
||||
ValueWithUnit.Percent(percent),
|
||||
ValueWithUnit.Minute(durationInMinutes))
|
||||
commandQueue.tempBasalPercent(percent, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
||||
} else {
|
||||
aapsLogger.debug("USER ENTRY: TEMP BASAL $absolute duration: $durationInMinutes")
|
||||
commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, callback)
|
||||
uel.log(Action.TEMP_BASAL, Sources.TempBasalDialog,
|
||||
ValueWithUnit.Insulin(absolute),
|
||||
ValueWithUnit.Minute(durationInMinutes))
|
||||
commandQueue.tempBasalAbsolute(absolute, durationInMinutes, true, profile, PumpSync.TemporaryBasalType.NORMAL, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -9,32 +9,44 @@ import com.google.common.base.Joiner
|
|||
import com.google.common.collect.Lists
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction
|
||||
import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction
|
||||
import info.nightscout.androidaps.databinding.DialogTemptargetBinding
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.db.TempTarget
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
class TempTargetDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
lateinit var reasonList: List<String>
|
||||
private lateinit var reasonList: List<String>
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private var _binding: DialogTemptargetBinding? = null
|
||||
|
||||
|
@ -45,7 +57,7 @@ class TempTargetDialog : DialogFragmentWithDate() {
|
|||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putDouble("duration", binding.duration.value)
|
||||
savedInstanceState.putDouble("temptarget", binding.temptarget.value)
|
||||
savedInstanceState.putDouble("tempTarget", binding.temptarget.value)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
|
@ -61,32 +73,32 @@ class TempTargetDialog : DialogFragmentWithDate() {
|
|||
binding.duration.setParams(savedInstanceState?.getDouble("duration")
|
||||
?: 0.0, 0.0, Constants.MAX_PROFILE_SWITCH_DURATION, 10.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
|
||||
if (profileFunction.getUnits() == Constants.MMOL)
|
||||
if (profileFunction.getUnits() == GlucoseUnit.MMOL)
|
||||
binding.temptarget.setParams(
|
||||
savedInstanceState?.getDouble("temptarget")
|
||||
savedInstanceState?.getDouble("tempTarget")
|
||||
?: 8.0,
|
||||
Constants.MIN_TT_MMOL, Constants.MAX_TT_MMOL, 0.1, DecimalFormat("0.0"), false, binding.okcancel.ok)
|
||||
else
|
||||
binding.temptarget.setParams(
|
||||
savedInstanceState?.getDouble("temptarget")
|
||||
savedInstanceState?.getDouble("tempTarget")
|
||||
?: 144.0,
|
||||
Constants.MIN_TT_MGDL, Constants.MAX_TT_MGDL, 1.0, DecimalFormat("0"), false, binding.okcancel.ok)
|
||||
|
||||
val units = profileFunction.getUnits()
|
||||
binding.units.text = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl)
|
||||
binding.units.text = if (units == GlucoseUnit.MMOL) rh.gs(R.string.mmol) else rh.gs(R.string.mgdl)
|
||||
|
||||
// temp target
|
||||
context?.let { context ->
|
||||
if (activePlugin.activeTreatments.tempTargetFromHistory != null)
|
||||
if (repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing)
|
||||
binding.targetCancel.visibility = View.VISIBLE
|
||||
else
|
||||
binding.targetCancel.visibility = View.GONE
|
||||
|
||||
reasonList = Lists.newArrayList(
|
||||
resourceHelper.gs(R.string.manual),
|
||||
resourceHelper.gs(R.string.eatingsoon),
|
||||
resourceHelper.gs(R.string.activity),
|
||||
resourceHelper.gs(R.string.hypo)
|
||||
rh.gs(R.string.manual),
|
||||
rh.gs(R.string.eatingsoon),
|
||||
rh.gs(R.string.activity),
|
||||
rh.gs(R.string.hypo)
|
||||
)
|
||||
val adapterReason = ArrayAdapter(context, R.layout.spinner_centered, reasonList)
|
||||
binding.reason.adapter = adapterReason
|
||||
|
@ -121,65 +133,88 @@ class TempTargetDialog : DialogFragmentWithDate() {
|
|||
R.id.eating_soon -> {
|
||||
binding.temptarget.value = defaultValueHelper.determineEatingSoonTT()
|
||||
binding.duration.value = defaultValueHelper.determineEatingSoonTTDuration().toDouble()
|
||||
binding.reason.setSelection(reasonList.indexOf(resourceHelper.gs(R.string.eatingsoon)))
|
||||
binding.reason.setSelection(reasonList.indexOf(rh.gs(R.string.eatingsoon)))
|
||||
}
|
||||
|
||||
R.id.activity -> {
|
||||
binding.temptarget.value = defaultValueHelper.determineActivityTT()
|
||||
binding.duration.value = defaultValueHelper.determineActivityTTDuration().toDouble()
|
||||
binding.reason.setSelection(reasonList.indexOf(resourceHelper.gs(R.string.activity)))
|
||||
binding.reason.setSelection(reasonList.indexOf(rh.gs(R.string.activity)))
|
||||
}
|
||||
|
||||
R.id.hypo -> {
|
||||
binding.temptarget.value = defaultValueHelper.determineHypoTT()
|
||||
binding.duration.value = defaultValueHelper.determineHypoTTDuration().toDouble()
|
||||
binding.reason.setSelection(reasonList.indexOf(resourceHelper.gs(R.string.hypo)))
|
||||
binding.reason.setSelection(reasonList.indexOf(rh.gs(R.string.hypo)))
|
||||
}
|
||||
|
||||
R.id.cancel -> {
|
||||
binding.duration.value = 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
val reason = binding.reason.selectedItem?.toString() ?: return false
|
||||
val unitResId = if (profileFunction.getUnits() == Constants.MGDL) R.string.mgdl else R.string.mmol
|
||||
var reason = binding.reason.selectedItem?.toString() ?: return false
|
||||
val unitResId = if (profileFunction.getUnits() == GlucoseUnit.MGDL) R.string.mgdl else R.string.mmol
|
||||
val target = binding.temptarget.value
|
||||
val duration = binding.duration.value.toInt()
|
||||
if (target != 0.0 && duration != 0) {
|
||||
actions.add(resourceHelper.gs(R.string.reason) + ": " + reason)
|
||||
actions.add(resourceHelper.gs(R.string.target_label) + ": " + Profile.toCurrentUnitsString(profileFunction, target) + " " + resourceHelper.gs(unitResId))
|
||||
actions.add(resourceHelper.gs(R.string.duration) + ": " + resourceHelper.gs(R.string.format_mins, duration))
|
||||
actions.add(rh.gs(R.string.reason) + ": " + reason)
|
||||
actions.add(rh.gs(R.string.target_label) + ": " + Profile.toCurrentUnitsString(profileFunction, target) + " " + rh.gs(unitResId))
|
||||
actions.add(rh.gs(R.string.duration) + ": " + rh.gs(R.string.format_mins, duration))
|
||||
} else {
|
||||
actions.add(resourceHelper.gs(R.string.stoptemptarget))
|
||||
actions.add(rh.gs(R.string.stoptemptarget))
|
||||
reason = rh.gs(R.string.stoptemptarget)
|
||||
}
|
||||
if (eventTimeChanged)
|
||||
actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
actions.add(rh.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(eventTime))
|
||||
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
aapsLogger.debug("USER ENTRY: TEMP TARGET $target duration: $duration")
|
||||
if (target == 0.0 || duration == 0) {
|
||||
val tempTarget = TempTarget()
|
||||
.date(eventTime)
|
||||
.duration(0)
|
||||
.low(0.0).high(0.0)
|
||||
.source(Source.USER)
|
||||
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
|
||||
} else {
|
||||
val tempTarget = TempTarget()
|
||||
.date(eventTime)
|
||||
.duration(duration)
|
||||
.reason(reason)
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(target, profileFunction.getUnits()))
|
||||
.high(Profile.toMgdl(target, profileFunction.getUnits()))
|
||||
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.careportal_temporarytarget), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
val units = profileFunction.getUnits()
|
||||
when(reason) {
|
||||
rh.gs(R.string.eatingsoon) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.EATING_SOON), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
|
||||
rh.gs(R.string.activity) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.ACTIVITY), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
|
||||
rh.gs(R.string.hypo) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.HYPOGLYCEMIA), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
|
||||
rh.gs(R.string.manual) -> uel.log(Action.TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged }, ValueWithUnit.TherapyEventTTReason(TemporaryTarget.Reason.CUSTOM), ValueWithUnit.fromGlucoseUnit(target, units.asText), ValueWithUnit.Minute(duration))
|
||||
rh.gs(R.string.stoptemptarget) -> uel.log(Action.CANCEL_TT, Sources.TTDialog, ValueWithUnit.Timestamp(eventTime).takeIf { eventTimeChanged })
|
||||
}
|
||||
if (target == 0.0 || duration == 0) {
|
||||
disposable += repository.runTransactionForResult(CancelCurrentTemporaryTargetIfAnyTransaction(eventTime))
|
||||
.subscribe({ result ->
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
} else {
|
||||
disposable += repository.runTransactionForResult(InsertAndCancelCurrentTemporaryTargetTransaction(
|
||||
timestamp = eventTime,
|
||||
duration = TimeUnit.MINUTES.toMillis(duration.toLong()),
|
||||
reason = when (reason) {
|
||||
rh.gs(R.string.eatingsoon) -> TemporaryTarget.Reason.EATING_SOON
|
||||
rh.gs(R.string.activity) -> TemporaryTarget.Reason.ACTIVITY
|
||||
rh.gs(R.string.hypo) -> TemporaryTarget.Reason.HYPOGLYCEMIA
|
||||
else -> TemporaryTarget.Reason.CUSTOM
|
||||
},
|
||||
lowTarget = Profile.toMgdl(target, profileFunction.getUnits()),
|
||||
highTarget = Profile.toMgdl(target, profileFunction.getUnits())
|
||||
)).subscribe({ result ->
|
||||
result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted temp target $it") }
|
||||
result.updated.forEach { aapsLogger.debug(LTag.DATABASE, "Updated temp target $it") }
|
||||
}, {
|
||||
aapsLogger.error(LTag.DATABASE, "Error while saving temporary target", it)
|
||||
})
|
||||
}
|
||||
|
||||
if (duration == 10) sp.putBoolean(R.string.key_objectiveusetemptarget, true)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -9,25 +8,31 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.google.common.base.Joiner
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.interfaces.Config
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.ValueWithUnit
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Action
|
||||
import info.nightscout.androidaps.database.entities.UserEntry.Sources
|
||||
import info.nightscout.androidaps.databinding.DialogTreatmentBinding
|
||||
import info.nightscout.androidaps.db.CareportalEvent
|
||||
import info.nightscout.androidaps.db.Source
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.CommandQueue
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
@ -36,11 +41,15 @@ import kotlin.math.abs
|
|||
class TreatmentDialog : DialogFragmentWithDate() {
|
||||
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var commandQueue: CommandQueue
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var config: Config
|
||||
@Inject lateinit var uel: UserEntryLogger
|
||||
@Inject lateinit var repository: AppRepository
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {}
|
||||
|
@ -55,11 +64,11 @@ class TreatmentDialog : DialogFragmentWithDate() {
|
|||
val maxInsulin = constraintChecker.getMaxBolusAllowed().value()
|
||||
if (SafeParse.stringToInt(binding.carbs.text) > maxCarbs) {
|
||||
binding.carbs.value = 0.0
|
||||
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.carbsconstraintapplied))
|
||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.carbsconstraintapplied))
|
||||
}
|
||||
if (SafeParse.stringToDouble(binding.insulin.text) > maxInsulin) {
|
||||
binding.insulin.value = 0.0
|
||||
ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.bolusconstraintapplied))
|
||||
ToastUtils.showToastInUiThread(context, rh.gs(R.string.bolusconstraintapplied))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,6 +105,7 @@ class TreatmentDialog : DialogFragmentWithDate() {
|
|||
?: 0.0, 0.0, maxCarbs, 1.0, DecimalFormat("0"), false, binding.okcancel.ok, textWatcher)
|
||||
binding.insulin.setParams(savedInstanceState?.getDouble("insulin")
|
||||
?: 0.0, 0.0, maxInsulin, pumpDescription.bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.okcancel.ok, textWatcher)
|
||||
binding.recordOnlyLayout.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -106,7 +116,7 @@ class TreatmentDialog : DialogFragmentWithDate() {
|
|||
override fun submit(): Boolean {
|
||||
if (_binding == null) return false
|
||||
val pumpDescription = activePlugin.activePump.pumpDescription
|
||||
val insulin = SafeParse.stringToDouble(binding.insulin.text ?: return false)
|
||||
val insulin = SafeParse.stringToDouble(binding.insulin.text)
|
||||
val carbs = SafeParse.stringToInt(binding.carbs.text)
|
||||
val recordOnlyChecked = binding.recordOnly.isChecked
|
||||
val actions: LinkedList<String?> = LinkedList()
|
||||
|
@ -114,48 +124,70 @@ class TreatmentDialog : DialogFragmentWithDate() {
|
|||
val carbsAfterConstraints = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
|
||||
|
||||
if (insulinAfterConstraints > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, resourceHelper).formatColor(resourceHelper, R.color.bolus))
|
||||
actions.add(rh.gs(R.string.bolus) + ": " + DecimalFormatter.toPumpSupportedBolus(insulinAfterConstraints, activePlugin.activePump, rh).formatColor(rh, R.color.bolus))
|
||||
if (recordOnlyChecked)
|
||||
actions.add(resourceHelper.gs(R.string.bolusrecordedonly).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.bolusrecordedonly).formatColor(rh, R.color.warning))
|
||||
if (abs(insulinAfterConstraints - insulin) > pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.bolusconstraintappliedwarn, insulin, insulinAfterConstraints).formatColor(rh, R.color.warning))
|
||||
}
|
||||
if (carbsAfterConstraints > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.carbs) + ": " + resourceHelper.gs(R.string.format_carbs, carbsAfterConstraints).formatColor(resourceHelper, R.color.carbs))
|
||||
actions.add(rh.gs(R.string.carbs) + ": " + rh.gs(R.string.format_carbs, carbsAfterConstraints).formatColor(rh, R.color.carbs))
|
||||
if (carbsAfterConstraints != carbs)
|
||||
actions.add(resourceHelper.gs(R.string.carbsconstraintapplied).formatColor(resourceHelper, R.color.warning))
|
||||
actions.add(rh.gs(R.string.carbsconstraintapplied).formatColor(rh, R.color.warning))
|
||||
}
|
||||
if (insulinAfterConstraints > 0 || carbsAfterConstraints > 0) {
|
||||
activity?.let { activity ->
|
||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
aapsLogger.debug("USER ENTRY: BOLUS insulin $insulin carbs: $carbs")
|
||||
OKDialog.showConfirmation(activity, rh.gs(R.string.overview_treatment_label), HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions)), {
|
||||
val action = when {
|
||||
insulinAfterConstraints.equals(0.0) -> Action.CARBS
|
||||
carbsAfterConstraints == 0 -> Action.BOLUS
|
||||
else -> Action.TREATMENT
|
||||
}
|
||||
val detailedBolusInfo = DetailedBolusInfo()
|
||||
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = CareportalEvent.CARBCORRECTION
|
||||
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS
|
||||
if (insulinAfterConstraints == 0.0) detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CARBS_CORRECTION
|
||||
if (carbsAfterConstraints == 0) detailedBolusInfo.eventType = DetailedBolusInfo.EventType.CORRECTION_BOLUS
|
||||
detailedBolusInfo.insulin = insulinAfterConstraints
|
||||
detailedBolusInfo.carbs = carbsAfterConstraints.toDouble()
|
||||
detailedBolusInfo.context = context
|
||||
detailedBolusInfo.source = Source.USER
|
||||
if (!(recordOnlyChecked && (detailedBolusInfo.insulin > 0 || pumpDescription.storesCarbInfo))) {
|
||||
if (recordOnlyChecked) {
|
||||
uel.log(action, Sources.TreatmentDialog, if (insulinAfterConstraints != 0.0) rh.gs(R.string.record) else "",
|
||||
ValueWithUnit.Timestamp(detailedBolusInfo.timestamp).takeIf { eventTimeChanged },
|
||||
ValueWithUnit.SimpleString(rh.gsNotLocalised(R.string.record)).takeIf { insulinAfterConstraints != 0.0 },
|
||||
ValueWithUnit.Insulin(insulinAfterConstraints).takeIf { insulinAfterConstraints != 0.0 },
|
||||
ValueWithUnit.Gram(carbsAfterConstraints).takeIf { carbsAfterConstraints != 0 })
|
||||
if (detailedBolusInfo.insulin > 0)
|
||||
disposable += repository.runTransactionForResult(detailedBolusInfo.insertBolusTransaction())
|
||||
.subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted bolus $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving bolus", it) }
|
||||
)
|
||||
if (detailedBolusInfo.carbs > 0)
|
||||
disposable += repository.runTransactionForResult(detailedBolusInfo.insertCarbsTransaction())
|
||||
.subscribe(
|
||||
{ result -> result.inserted.forEach { aapsLogger.debug(LTag.DATABASE, "Inserted carbs $it") } },
|
||||
{ aapsLogger.error(LTag.DATABASE, "Error while saving carbs", it) }
|
||||
)
|
||||
} else {
|
||||
if (detailedBolusInfo.insulin > 0) {
|
||||
uel.log(action, Sources.TreatmentDialog,
|
||||
ValueWithUnit.Insulin(insulinAfterConstraints),
|
||||
ValueWithUnit.Gram(carbsAfterConstraints).takeIf { carbsAfterConstraints != 0 })
|
||||
commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
ErrorHelperActivity.runAlarm(ctx, result.comment, rh.gs(R.string.treatmentdeliveryerror), R.raw.boluserror)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else
|
||||
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
|
||||
uel.log(action, Sources.TreatmentDialog,
|
||||
ValueWithUnit.Gram(carbsAfterConstraints).takeIf { carbs != 0 })
|
||||
}
|
||||
})
|
||||
}
|
||||
} else
|
||||
activity?.let { activity ->
|
||||
OKDialog.show(activity, resourceHelper.gs(R.string.overview_treatment_label), resourceHelper.gs(R.string.no_action_selected))
|
||||
OKDialog.show(activity, rh.gs(R.string.overview_treatment_label), rh.gs(R.string.no_action_selected))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
|
@ -13,32 +14,29 @@ import android.widget.AdapterView.OnItemSelectedListener
|
|||
import android.widget.ArrayAdapter
|
||||
import android.widget.CompoundButton
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import dagger.android.HasAndroidInjector
|
||||
import dagger.android.support.DaggerDialogFragment
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.data.ProfileSealed
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.databinding.DialogWizardBinding
|
||||
import info.nightscout.androidaps.db.BgReading
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.extensions.formatColor
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.SafeParse
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.extensions.toVisibility
|
||||
import info.nightscout.androidaps.extensions.valueToUnits
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.androidaps.utils.*
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
@ -47,19 +45,27 @@ import kotlin.math.abs
|
|||
|
||||
class WizardDialog : DaggerDialogFragment() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var ctx: Context
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
private var wizard: BolusWizard? = null
|
||||
private var calculatedPercentage = 100.0
|
||||
private var calculatedCorrection = 0.0
|
||||
private var correctionPercent = false
|
||||
private var carbsPassedIntoWizard = 0.0
|
||||
private var notesPassedIntoWizard = ""
|
||||
|
||||
//one shot guards
|
||||
private var okClicked: Boolean = false
|
||||
|
@ -82,6 +88,7 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
}
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
private var bolusStep = 0.0
|
||||
|
||||
private var _binding: DialogWizardBinding? = null
|
||||
|
||||
|
@ -92,6 +99,7 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
aapsLogger.debug(LTag.APS, "Dialog opened: ${this.javaClass.name}")
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
|
@ -104,6 +112,11 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
this.arguments?.let { bundle ->
|
||||
carbsPassedIntoWizard = bundle.getInt("carbs_input").toDouble()
|
||||
notesPassedIntoWizard = bundle.getString("notes_input").toString()
|
||||
}
|
||||
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
isCancelable = true
|
||||
|
@ -116,13 +129,14 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
loadCheckedStates()
|
||||
processCobCheckBox()
|
||||
binding.sbcheckbox.visibility = sp.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||
binding.sbCheckbox.visibility = sp.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||
binding.notesLayout.visibility = sp.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||
|
||||
val maxCarbs = constraintChecker.getMaxCarbsAllowed().value()
|
||||
val maxCorrection = constraintChecker.getMaxBolusAllowed().value()
|
||||
bolusStep = activePlugin.activePump.pumpDescription.bolusStep
|
||||
|
||||
if (profileFunction.getUnits() == Constants.MGDL)
|
||||
if (profileFunction.getUnits() == GlucoseUnit.MGDL)
|
||||
binding.bgInput.setParams(savedInstanceState?.getDouble("bg_input")
|
||||
?: 0.0, 0.0, 500.0, 1.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
|
||||
else
|
||||
|
@ -130,14 +144,23 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
?: 0.0, 0.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.ok, textWatcher)
|
||||
binding.carbsInput.setParams(savedInstanceState?.getDouble("carbs_input")
|
||||
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
|
||||
val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
|
||||
binding.correctionInput.setParams(savedInstanceState?.getDouble("correction_input")
|
||||
|
||||
if (correctionPercent) {
|
||||
calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
|
||||
binding.correctionInput.setParams(calculatedPercentage, 10.0, 200.0, 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
|
||||
binding.correctionInput.value = calculatedPercentage
|
||||
binding.correctionUnit.text = "%"
|
||||
} else {
|
||||
binding.correctionInput.setParams(
|
||||
savedInstanceState?.getDouble("correction_input")
|
||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
|
||||
binding.correctionUnit.text = rh.gs(R.string.insulin_unit_shortname)
|
||||
}
|
||||
binding.carbTimeInput.setParams(savedInstanceState?.getDouble("carb_time_input")
|
||||
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
|
||||
initDialog()
|
||||
|
||||
binding.percentUsed.text = resourceHelper.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
|
||||
calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
|
||||
binding.percentUsed.text = rh.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
|
||||
// ok button
|
||||
binding.ok.setOnClickListener {
|
||||
if (okClicked) {
|
||||
|
@ -148,35 +171,59 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
context?.let { context ->
|
||||
wizard?.confirmAndExecute(context)
|
||||
}
|
||||
aapsLogger.debug(LTag.APS, "Dialog ok pressed: ${this.javaClass.name}")
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
binding.bgEnabledIcon.setOnClickListener { binding.bgCheckbox.isChecked = !binding.bgCheckbox.isChecked }
|
||||
binding.trendEnabledIcon.setOnClickListener { binding.bgTrendCheckbox.isChecked = !binding.bgTrendCheckbox.isChecked }
|
||||
binding.cobEnabledIcon.setOnClickListener { binding.cobCheckbox.isChecked = !binding.cobCheckbox.isChecked; processCobCheckBox(); }
|
||||
binding.iobEnabledIcon.setOnClickListener { if (!binding.cobCheckbox.isChecked) binding.iobCheckbox.isChecked = !binding.iobCheckbox.isChecked }
|
||||
// cancel button
|
||||
binding.cancel.setOnClickListener { dismiss() }
|
||||
binding.cancel.setOnClickListener {
|
||||
aapsLogger.debug(LTag.APS, "Dialog canceled: ${this.javaClass.name}")
|
||||
dismiss()
|
||||
}
|
||||
// checkboxes
|
||||
binding.bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bgCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.ttCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.cobCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.iobCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bgTrendCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.sbCheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
|
||||
val showCalc = sp.getBoolean(R.string.key_wizard_calculation_visible, false)
|
||||
binding.delimiter.visibility = showCalc.toVisibility()
|
||||
binding.resulttable.visibility = showCalc.toVisibility()
|
||||
binding.calculationcheckbox.isChecked = showCalc
|
||||
binding.calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
binding.result.visibility = showCalc.toVisibility()
|
||||
binding.calculationCheckbox.isChecked = showCalc
|
||||
binding.calculationCheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
run {
|
||||
sp.putBoolean(resourceHelper.gs(R.string.key_wizard_calculation_visible), isChecked)
|
||||
sp.putBoolean(rh.gs(R.string.key_wizard_calculation_visible), isChecked)
|
||||
binding.delimiter.visibility = isChecked.toVisibility()
|
||||
binding.resulttable.visibility = isChecked.toVisibility()
|
||||
binding.result.visibility = isChecked.toVisibility()
|
||||
processEnabledIcons()
|
||||
}
|
||||
}
|
||||
|
||||
processEnabledIcons()
|
||||
|
||||
binding.correctionPercent.setOnCheckedChangeListener {_, isChecked ->
|
||||
run {
|
||||
sp.putBoolean(rh.gs(R.string.key_wizard_correction_percent), isChecked)
|
||||
binding.correctionUnit.text = if (isChecked) "%" else rh.gs(R.string.insulin_unit_shortname)
|
||||
correctionPercent = binding.correctionPercent.isChecked
|
||||
if (correctionPercent)
|
||||
binding.correctionInput.setParams(calculatedPercentage, 10.0, 200.0, 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
|
||||
else
|
||||
binding.correctionInput.setParams(savedInstanceState?.getDouble("correction_input")
|
||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
|
||||
binding.correctionInput.value = if (correctionPercent) calculatedPercentage else Round.roundTo(calculatedCorrection, bolusStep)
|
||||
}
|
||||
}
|
||||
// profile spinner
|
||||
binding.profile.onItemSelectedListener = object : OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.noprofileselected))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofileset))
|
||||
binding.ok.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
@ -188,10 +235,10 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
// bus
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
activity?.runOnUiThread { calculateInsulin() }
|
||||
}, { fabricPrivacy.logException(it) })
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
|
||||
}
|
||||
|
@ -204,176 +251,205 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
|
||||
private fun onCheckedChanged(buttonView: CompoundButton, @Suppress("UNUSED_PARAMETER") state: Boolean) {
|
||||
saveCheckedStates()
|
||||
binding.ttcheckbox.isEnabled = binding.bgcheckbox.isChecked && treatmentsPlugin.tempTargetFromHistory != null
|
||||
if (buttonView.id == binding.cobcheckbox.id)
|
||||
binding.ttCheckbox.isEnabled = binding.bgCheckbox.isChecked && repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
||||
if (buttonView.id == binding.cobCheckbox.id)
|
||||
processCobCheckBox()
|
||||
processEnabledIcons()
|
||||
calculateInsulin()
|
||||
}
|
||||
|
||||
private fun processCobCheckBox() {
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
binding.bolusiobcheckbox.isEnabled = false
|
||||
binding.basaliobcheckbox.isEnabled = false
|
||||
binding.bolusiobcheckbox.isChecked = true
|
||||
binding.basaliobcheckbox.isChecked = true
|
||||
if (binding.cobCheckbox.isChecked) {
|
||||
binding.iobCheckbox.isEnabled = false
|
||||
binding.iobCheckbox.isChecked = true
|
||||
} else {
|
||||
binding.bolusiobcheckbox.isEnabled = true
|
||||
binding.basaliobcheckbox.isEnabled = true
|
||||
binding.iobCheckbox.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun processEnabledIcons() {
|
||||
binding.bgEnabledIcon.alpha = if (binding.bgCheckbox.isChecked) 1.0f else 0.2f
|
||||
binding.trendEnabledIcon.alpha = if (binding.bgTrendCheckbox.isChecked) 1.0f else 0.2f
|
||||
binding.iobEnabledIcon.alpha = if (binding.iobCheckbox.isChecked) 1.0f else 0.2f
|
||||
binding.cobEnabledIcon.alpha = if (binding.cobCheckbox.isChecked) 1.0f else 0.2f
|
||||
binding.bgEnabledIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
|
||||
binding.trendEnabledIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
|
||||
binding.iobEnabledIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
|
||||
binding.cobEnabledIcon.visibility = binding.calculationCheckbox.isChecked.not().toVisibility()
|
||||
}
|
||||
|
||||
private fun saveCheckedStates() {
|
||||
sp.putBoolean(R.string.key_wizard_include_cob, binding.cobcheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_include_trend_bg, binding.bgtrendcheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_include_cob, binding.cobCheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_include_trend_bg, binding.bgTrendCheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_correction_percent, binding.correctionPercent.isChecked)
|
||||
}
|
||||
|
||||
private fun loadCheckedStates() {
|
||||
binding.bgtrendcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_trend_bg, false)
|
||||
binding.cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
|
||||
binding.bgTrendCheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_trend_bg, false)
|
||||
binding.cobCheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
|
||||
correctionPercent = sp.getBoolean(R.string.key_wizard_correction_percent,false)
|
||||
binding.correctionPercent.isChecked = correctionPercent
|
||||
}
|
||||
|
||||
private fun valueToUnitsToString(value: Double, units: String): String =
|
||||
if (units == Constants.MGDL) DecimalFormatter.to0Decimal(value)
|
||||
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
|
||||
|
||||
private fun initDialog() {
|
||||
if(carbsPassedIntoWizard != 0.0) {
|
||||
binding.carbsInput.value = carbsPassedIntoWizard
|
||||
}
|
||||
if(notesPassedIntoWizard.isNotBlank()) {
|
||||
binding.notes.setText(notesPassedIntoWizard)
|
||||
}
|
||||
val profile = profileFunction.getProfile()
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
|
||||
if (profile == null || profileStore == null) {
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.noprofile))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.noprofile))
|
||||
dismiss()
|
||||
return
|
||||
}
|
||||
|
||||
val profileList: ArrayList<CharSequence>
|
||||
profileList = profileStore.getProfileList()
|
||||
profileList.add(0, resourceHelper.gs(R.string.active))
|
||||
val profileList: ArrayList<CharSequence> = profileStore.getProfileList()
|
||||
profileList.add(0, rh.gs(R.string.active))
|
||||
context?.let { context ->
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
binding.profile.adapter = adapter
|
||||
} ?: return
|
||||
|
||||
val units = profileFunction.getUnits()
|
||||
binding.bgunits.text = units
|
||||
if (units == Constants.MGDL)
|
||||
binding.bgInput.setStep(1.0)
|
||||
else
|
||||
binding.bgInput.setStep(0.1)
|
||||
binding.bgUnits.text = units.asText
|
||||
binding.bgInput.step = if (units == GlucoseUnit.MGDL) 1.0 else 0.1
|
||||
|
||||
// Set BG if not old
|
||||
val lastBg = iobCobCalculatorPlugin.actualBg()
|
||||
|
||||
if (lastBg != null) {
|
||||
binding.bgInput.value = lastBg.valueToUnits(units)
|
||||
} else {
|
||||
binding.bgInput.value = 0.0
|
||||
}
|
||||
binding.ttcheckbox.isEnabled = treatmentsPlugin.tempTargetFromHistory != null
|
||||
binding.bgInput.value = iobCobCalculator.ads.actualBg()?.valueToUnits(units) ?: 0.0
|
||||
binding.ttCheckbox.isEnabled = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet() is ValueWrapper.Existing
|
||||
|
||||
// IOB calculation
|
||||
treatmentsPlugin.updateTotalIOBTreatments()
|
||||
val bolusIob = treatmentsPlugin.lastCalculationTreatments.round()
|
||||
treatmentsPlugin.updateTotalIOBTempBasals()
|
||||
val basalIob = treatmentsPlugin.lastCalculationTempBasals.round()
|
||||
val bolusIob = iobCobCalculator.calculateIobFromBolus().round()
|
||||
val basalIob = iobCobCalculator.calculateIobFromTempBasalsIncludingConvertedExtended().round()
|
||||
|
||||
binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -bolusIob.iob)
|
||||
binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -basalIob.basaliob)
|
||||
binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, -bolusIob.iob - basalIob.basaliob)
|
||||
|
||||
calculateInsulin()
|
||||
|
||||
binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
|
||||
binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility()
|
||||
}
|
||||
|
||||
private fun calculateInsulin() {
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
val profileStore = activePlugin.activeProfileSource.profile
|
||||
if (binding.profile.selectedItem == null || profileStore == null)
|
||||
return // not initialized yet
|
||||
var profileName = binding.profile.selectedItem.toString()
|
||||
val specificProfile: Profile?
|
||||
if (profileName == resourceHelper.gs(R.string.active)) {
|
||||
if (profileName == rh.gs(R.string.active)) {
|
||||
specificProfile = profileFunction.getProfile()
|
||||
profileName = profileFunction.getProfileName()
|
||||
} else
|
||||
specificProfile = profileStore.getSpecificProfile(profileName)
|
||||
specificProfile = profileStore.getSpecificProfile(profileName)?.let { ProfileSealed.Pure(it) }
|
||||
|
||||
if (specificProfile == null) return
|
||||
|
||||
// Entered values
|
||||
val usePercentage = binding.correctionPercent.isChecked
|
||||
var bg = SafeParse.stringToDouble(binding.bgInput.text)
|
||||
val carbs = SafeParse.stringToInt(binding.carbsInput.text)
|
||||
val correction = SafeParse.stringToDouble(binding.correctionInput.text)
|
||||
val correction = if (!usePercentage) {
|
||||
if (Round.roundTo(calculatedCorrection, bolusStep) == SafeParse.stringToDouble(binding.correctionInput.text))
|
||||
calculatedCorrection
|
||||
else
|
||||
SafeParse.stringToDouble(binding.correctionInput.text)
|
||||
} else
|
||||
0.0
|
||||
val percentageCorrection = if (usePercentage) {
|
||||
if (Round.roundTo(calculatedPercentage,1.0) == SafeParse.stringToDouble(binding.correctionInput.text))
|
||||
calculatedPercentage
|
||||
else
|
||||
SafeParse.stringToDouble(binding.correctionInput.text)
|
||||
} else
|
||||
sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
|
||||
val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
|
||||
if (abs(carbs - carbsAfterConstraint) > 0.01) {
|
||||
binding.carbsInput.value = 0.0
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.carbsconstraintapplied))
|
||||
ToastUtils.showToastInUiThread(ctx, rh.gs(R.string.carbsconstraintapplied))
|
||||
return
|
||||
}
|
||||
|
||||
bg = if (binding.bgcheckbox.isChecked) bg else 0.0
|
||||
val tempTarget = if (binding.ttcheckbox.isChecked) treatmentsPlugin.tempTargetFromHistory else null
|
||||
bg = if (binding.bgCheckbox.isChecked) bg else 0.0
|
||||
val dbRecord = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||
val tempTarget = if (binding.ttCheckbox.isChecked && dbRecord is ValueWrapper.Existing) dbRecord.value else null
|
||||
|
||||
// COB
|
||||
var cob = 0.0
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
val cobInfo = iobCobCalculatorPlugin.getCobInfo(false, "Wizard COB")
|
||||
if (binding.cobCheckbox.isChecked) {
|
||||
val cobInfo = iobCobCalculator.getCobInfo(false, "Wizard COB")
|
||||
cobInfo.displayCob?.let { cob = it }
|
||||
}
|
||||
|
||||
val carbTime = SafeParse.stringToInt(binding.carbTimeInput.text)
|
||||
|
||||
wizard = BolusWizard(mainApp).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
||||
sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||
binding.bgcheckbox.isChecked,
|
||||
binding.cobcheckbox.isChecked,
|
||||
binding.bolusiobcheckbox.isChecked,
|
||||
binding.basaliobcheckbox.isChecked,
|
||||
binding.sbcheckbox.isChecked,
|
||||
binding.ttcheckbox.isChecked,
|
||||
binding.bgtrendcheckbox.isChecked,
|
||||
wizard = BolusWizard(injector).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction, sp.getInt(R.string.key_boluswizard_percentage, 100),
|
||||
binding.bgCheckbox.isChecked,
|
||||
binding.cobCheckbox.isChecked,
|
||||
binding.iobCheckbox.isChecked,
|
||||
binding.iobCheckbox.isChecked,
|
||||
binding.sbCheckbox.isChecked,
|
||||
binding.ttCheckbox.isChecked,
|
||||
binding.bgTrendCheckbox.isChecked,
|
||||
binding.alarm.isChecked,
|
||||
binding.notes.text.toString(), carbTime)
|
||||
binding.notes.text.toString(),
|
||||
carbTime,
|
||||
usePercentage = usePercentage,
|
||||
totalPercentage = percentageCorrection
|
||||
)
|
||||
|
||||
wizard?.let { wizard ->
|
||||
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, profileFunction.getUnits())).valueToUnitsToString(profileFunction.getUnits()), wizard.sens)
|
||||
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
||||
binding.bg.text = String.format(rh.gs(R.string.format_bg_isf), valueToUnitsToString(Profile.toMgdl(bg, profileFunction.getUnits()), profileFunction.getUnits().asText), wizard.sens)
|
||||
binding.bgInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
||||
|
||||
binding.carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||
binding.carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCarbs)
|
||||
binding.carbs.text = String.format(rh.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||
binding.carbsInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromCarbs)
|
||||
|
||||
binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBolusIOB)
|
||||
binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBasalIOB)
|
||||
binding.iobInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromBolusIOB + wizard.insulinFromBasalIOB)
|
||||
|
||||
binding.correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCorrection)
|
||||
binding.correctionInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromCorrection)
|
||||
|
||||
// Superbolus
|
||||
binding.sb.text = if (binding.sbcheckbox.isChecked) resourceHelper.gs(R.string.twohours) else ""
|
||||
binding.sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromSuperBolus)
|
||||
binding.sb.text = if (binding.sbCheckbox.isChecked) rh.gs(R.string.twohours) else ""
|
||||
binding.sbInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromSuperBolus)
|
||||
|
||||
// Trend
|
||||
if (binding.bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||
binding.bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||
if (binding.bgTrendCheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||
binding.bgTrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, profileFunction.getUnits())
|
||||
+ " " + profileFunction.getUnits())
|
||||
} else {
|
||||
binding.bgtrend.text = ""
|
||||
binding.bgTrend.text = ""
|
||||
}
|
||||
binding.bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromTrend)
|
||||
binding.bgTrendInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromTrend)
|
||||
|
||||
// COB
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
binding.cob.text = String.format(resourceHelper.gs(R.string.format_cob_ic), cob, wizard.ic)
|
||||
binding.cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCOB)
|
||||
if (binding.cobCheckbox.isChecked) {
|
||||
binding.cob.text = String.format(rh.gs(R.string.format_cob_ic), cob, wizard.ic)
|
||||
binding.cobInsulin.text = rh.gs(R.string.formatinsulinunits, wizard.insulinFromCOB)
|
||||
} else {
|
||||
binding.cob.text = ""
|
||||
binding.cobinsulin.text = ""
|
||||
binding.cobInsulin.text = ""
|
||||
}
|
||||
|
||||
if (wizard.calculatedTotalInsulin > 0.0 || carbsAfterConstraint > 0.0) {
|
||||
val insulinText = if (wizard.calculatedTotalInsulin > 0.0) resourceHelper.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin) else ""
|
||||
val carbsText = if (carbsAfterConstraint > 0.0) resourceHelper.gs(R.string.format_carbs, carbsAfterConstraint) else ""
|
||||
binding.total.text = resourceHelper.gs(R.string.result_insulin_carbs, insulinText, carbsText)
|
||||
val insulinText = if (wizard.calculatedTotalInsulin > 0.0) rh.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin).formatColor(rh, R.color.bolus) else ""
|
||||
val carbsText = if (carbsAfterConstraint > 0.0) rh.gs(R.string.format_carbs, carbsAfterConstraint).formatColor(rh, R.color.carbs) else ""
|
||||
binding.total.text = HtmlHelper.fromHtml(rh.gs(R.string.result_insulin_carbs, insulinText, carbsText))
|
||||
binding.ok.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.total.text = resourceHelper.gs(R.string.missing_carbs, wizard.carbsEquivalent.toInt())
|
||||
binding.total.text = HtmlHelper.fromHtml(rh.gs(R.string.missing_carbs, wizard.carbsEquivalent.toInt()).formatColor(rh, R.color.carbs))
|
||||
binding.ok.visibility = View.INVISIBLE
|
||||
}
|
||||
binding.percentUsed.text = rh.gs(R.string.format_percent, wizard.percentageCorrection)
|
||||
calculatedPercentage = wizard.calculatedPercentage
|
||||
calculatedCorrection = wizard.calculatedCorrection
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -385,7 +461,7 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
it.commitAllowingStateLoss()
|
||||
}
|
||||
} catch (e: IllegalStateException) {
|
||||
aapsLogger.debug(e.localizedMessage)
|
||||
aapsLogger.debug(e.localizedMessage ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,23 +9,28 @@ import android.view.WindowManager
|
|||
import dagger.android.support.DaggerDialogFragment
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.database.entities.BolusCalculatorResult
|
||||
import info.nightscout.androidaps.databinding.DialogWizardinfoBinding
|
||||
import info.nightscout.androidaps.extensions.bolusCalculatorResultFromJson
|
||||
import info.nightscout.androidaps.extensions.toJson
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
|
||||
class WizardInfoDialog : DaggerDialogFragment() {
|
||||
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
private var json: JSONObject? = null
|
||||
private lateinit var data: BolusCalculatorResult
|
||||
|
||||
fun setData(json: JSONObject) {
|
||||
this.json = json
|
||||
fun setData(bolusCalculatorResult: BolusCalculatorResult) {
|
||||
this.data = bolusCalculatorResult
|
||||
}
|
||||
|
||||
private var _binding: DialogWizardinfoBinding? = null
|
||||
|
@ -34,8 +39,7 @@ class WizardInfoDialog : DaggerDialogFragment() {
|
|||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
isCancelable = true
|
||||
|
@ -44,49 +48,62 @@ class WizardInfoDialog : DaggerDialogFragment() {
|
|||
return binding.root
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
savedInstanceState?.getString("data")?.let { str ->
|
||||
val json = JSONObject(str).apply {
|
||||
put("mills", dateUtil.now()) // fake NS response
|
||||
}
|
||||
data = bolusCalculatorResultFromJson(json) ?: return
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putString("data", data.toJson(true, dateUtil).toString())
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.close.setOnClickListener { dismiss() }
|
||||
val units = profileFunction.getUnits()
|
||||
val bgString =
|
||||
if (units == Constants.MGDL) DecimalFormatter.to0Decimal(JsonHelper.safeGetDouble(json, "bg"))
|
||||
else DecimalFormatter.to1Decimal(JsonHelper.safeGetDouble(json, "bg"))
|
||||
val bgString = Profile.toUnitsString(data.glucoseValue, data.glucoseValue * Constants.MGDL_TO_MMOLL, units)
|
||||
// BG
|
||||
binding.bg.text = resourceHelper.gs(R.string.format_bg_isf, bgString, JsonHelper.safeGetDouble(json, "isf"))
|
||||
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulinbg"))
|
||||
binding.bgcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "insulinbgused")
|
||||
binding.ttcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "ttused")
|
||||
binding.bg.text = rh.gs(R.string.format_bg_isf, bgString, data.isf)
|
||||
binding.bgInsulin.text = rh.gs(R.string.formatinsulinunits, data.glucoseInsulin)
|
||||
binding.bgCheckbox.isChecked = data.wasGlucoseUsed
|
||||
binding.ttCheckbox.isChecked = data.wasTempTargetUsed
|
||||
// Trend
|
||||
binding.bgtrend.text = JsonHelper.safeGetString(json, "trend")
|
||||
binding.bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulintrend"))
|
||||
binding.bgtrendcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "trendused")
|
||||
binding.bgTrend.text = DecimalFormatter.to1Decimal(data.glucoseTrend)
|
||||
binding.bgTrendInsulin.text = rh.gs(R.string.formatinsulinunits, data.trendInsulin)
|
||||
binding.bgTrendCheckbox.isChecked = data.wasTrendUsed
|
||||
// COB
|
||||
binding.cob.text = resourceHelper.gs(R.string.format_cob_ic, JsonHelper.safeGetDouble(json, "cob"), JsonHelper.safeGetDouble(json, "ic"))
|
||||
binding.cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulincob"))
|
||||
binding.cobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "cobused")
|
||||
binding.cob.text = rh.gs(R.string.format_cob_ic, data.cob, data.ic)
|
||||
binding.cobInsulin.text = rh.gs(R.string.formatinsulinunits, data.cobInsulin)
|
||||
binding.cobCheckbox.isChecked = data.wasCOBUsed
|
||||
// Bolus IOB
|
||||
binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "bolusiob"))
|
||||
binding.bolusiobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "bolusiobused")
|
||||
binding.bolusIobInsulin.text = rh.gs(R.string.formatinsulinunits, data.bolusIOB)
|
||||
binding.bolusIobCheckbox.isChecked = data.wasBolusIOBUsed
|
||||
// Basal IOB
|
||||
binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "basaliob"))
|
||||
binding.basaliobcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "basaliobused")
|
||||
binding.basalIobInsulin.text = rh.gs(R.string.formatinsulinunits, data.basalIOB)
|
||||
binding.basalIobCheckbox.isChecked = data.wasBasalIOBUsed
|
||||
// Superbolus
|
||||
binding.sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulinsuperbolus"))
|
||||
binding.sbcheckbox.isChecked = JsonHelper.safeGetBoolean(json, "superbolusused")
|
||||
binding.sbinsulin.text = rh.gs(R.string.formatinsulinunits, data.superbolusInsulin)
|
||||
binding.sbCheckbox.isChecked = data.wasSuperbolusUsed
|
||||
// Carbs
|
||||
binding.carbs.text = resourceHelper.gs(R.string.format_carbs_ic, JsonHelper.safeGetDouble(json, "carbs"), JsonHelper.safeGetDouble(json, "ic"))
|
||||
binding.carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulincarbs"))
|
||||
binding.carbs.text = rh.gs(R.string.format_carbs_ic, data.carbs, data.ic)
|
||||
binding.carbsinsulin.text = rh.gs(R.string.formatinsulinunits, data.carbsInsulin)
|
||||
// Correction
|
||||
binding.correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "othercorrection"))
|
||||
binding.correctioninsulin.text = rh.gs(R.string.formatinsulinunits, data.otherCorrection)
|
||||
// Profile
|
||||
binding.profile.text = JsonHelper.safeGetString(json, "profile")
|
||||
binding.profile.text = data.profileName
|
||||
// Notes
|
||||
binding.notes.text = JsonHelper.safeGetString(json, "notes")
|
||||
binding.notes.text = data.note
|
||||
// Percentage
|
||||
binding.percentUsed.text = resourceHelper.gs(R.string.format_percent, (JsonHelper.safeGetInt(json, "percentageCorrection", 100)))
|
||||
binding.percentUsed.text = rh.gs(R.string.format_percent, data.percentageCorrection)
|
||||
// Total
|
||||
binding.totalinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, JsonHelper.safeGetDouble(json, "insulin"))
|
||||
binding.totalinsulin.text = rh.gs(R.string.formatinsulinunits, data.totalInsulin)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventCareportalEventChange : Event()
|
|
@ -1,5 +1,5 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
import info.nightscout.androidaps.db.BgReading
|
||||
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||
|
||||
class EventNewBG(val bgReading: BgReading?) : EventLoop()
|
||||
class EventNewBG(val glucoseValue: GlucoseValue?) : EventLoop()
|
|
@ -1,3 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventNewBasalProfile : Event()
|
|
@ -1,20 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
import org.json.JSONArray
|
||||
|
||||
/**
|
||||
* Event which is published with data fetched from NightScout specific for the
|
||||
* Food-class.
|
||||
*
|
||||
* Payload is the from NS retrieved JSON-String which should be handled by all
|
||||
* subscriber.
|
||||
*/
|
||||
|
||||
class EventNsFood(val mode: Int, val foods: JSONArray) : Event() {
|
||||
|
||||
companion object {
|
||||
val ADD = 0
|
||||
val UPDATE = 1
|
||||
val REMOVE = 2
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
import org.json.JSONObject
|
||||
|
||||
|
||||
/**
|
||||
* Event which is published with data fetched from NightScout specific for the
|
||||
* Treatment-class.
|
||||
*
|
||||
*
|
||||
* Payload is the from NS retrieved JSON-String which should be handled by all
|
||||
* subscriber.
|
||||
*/
|
||||
|
||||
class EventNsTreatment(val mode: Int, val payload: JSONObject) : Event() {
|
||||
companion object {
|
||||
val ADD = 0
|
||||
val UPDATE = 1
|
||||
val REMOVE = 2
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventReloadTempBasalData : Event()
|
|
@ -1,3 +0,0 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventReloadTreatmentData(var next: Event) : Event()
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventTherapyEventChange : Event()
|
|
@ -1,5 +1,3 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
import info.nightscout.androidaps.db.Treatment
|
||||
|
||||
class EventTreatmentChange(val treatment: Treatment?) : EventLoop()
|
||||
class EventTreatmentChange : EventLoop()
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
package info.nightscout.androidaps.events
|
||||
|
||||
class EventTreatmentUpdateGui : EventUpdateGui()
|
|
@ -1,376 +0,0 @@
|
|||
package info.nightscout.androidaps.historyBrowser
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.jjoe64.graphview.GraphView
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensBgLoaded
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlinx.android.synthetic.main.activity_historybrowse.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var iobCobCalculatorPluginHistory: IobCobCalculatorPluginHistory
|
||||
@Inject lateinit var treatmentsPluginHistory: TreatmentsPluginHistory
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var overviewMenus: OverviewMenus
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val secondaryGraphs = ArrayList<GraphView>()
|
||||
private val secondaryGraphsLabel = ArrayList<TextView>()
|
||||
|
||||
private var axisWidth: Int = 0
|
||||
private var rangeToDisplay = 24 // for graph
|
||||
private var start: Long = 0
|
||||
|
||||
private val graphLock = Object()
|
||||
|
||||
private var eventCustomCalculationFinished = EventCustomCalculationFinished()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_historybrowse)
|
||||
|
||||
historybrowse_left.setOnClickListener {
|
||||
start -= T.hours(rangeToDisplay.toLong()).msecs()
|
||||
runCalculation("onClickLeft")
|
||||
}
|
||||
historybrowse_right.setOnClickListener {
|
||||
start += T.hours(rangeToDisplay.toLong()).msecs()
|
||||
runCalculation("onClickRight")
|
||||
}
|
||||
historybrowse_end.setOnClickListener {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
runCalculation("onClickEnd")
|
||||
}
|
||||
historybrowse_zoom.setOnClickListener {
|
||||
rangeToDisplay += 6
|
||||
rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay
|
||||
updateGUI("rangeChange", false)
|
||||
}
|
||||
historybrowse_zoom.setOnLongClickListener {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = start
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
runCalculation("onLongClickZoom")
|
||||
true
|
||||
}
|
||||
|
||||
// create an OnDateSetListener
|
||||
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = start
|
||||
cal[Calendar.YEAR] = year
|
||||
cal[Calendar.MONTH] = monthOfYear
|
||||
cal[Calendar.DAY_OF_MONTH] = dayOfMonth
|
||||
cal[Calendar.MILLISECOND] = 0
|
||||
cal[Calendar.SECOND] = 0
|
||||
cal[Calendar.MINUTE] = 0
|
||||
cal[Calendar.HOUR_OF_DAY] = 0
|
||||
start = cal.timeInMillis
|
||||
historybrowse_date?.text = dateUtil.dateAndTimeString(start)
|
||||
runCalculation("onClickDate")
|
||||
}
|
||||
|
||||
historybrowse_date.setOnClickListener {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = start
|
||||
DatePickerDialog(this, dateSetListener,
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
|
||||
val dm = DisplayMetrics()
|
||||
windowManager?.defaultDisplay?.getMetrics(dm)
|
||||
|
||||
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
|
||||
historybrowse_bggraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
|
||||
historybrowse_bggraph?.gridLabelRenderer?.reloadStyles()
|
||||
historybrowse_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
|
||||
overviewMenus.setupChartMenu(overview_chartMenuButton)
|
||||
prepareGraphsIfNeeded(overviewMenus.setting.size)
|
||||
savedInstanceState?.let { bundle ->
|
||||
rangeToDisplay = bundle.getInt("rangeToDisplay", 0)
|
||||
start = bundle.getLong("start", 0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
iobCobCalculatorPluginHistory.stopCalculation("onPause")
|
||||
}
|
||||
|
||||
public override fun onResume() {
|
||||
super.onResume()
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe({
|
||||
// catch only events from iobCobCalculatorPluginHistory
|
||||
if (it.cause is EventCustomCalculationFinished) {
|
||||
updateGUI("EventAutosensCalculationFinished", bgOnly = false)
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAutosensBgLoaded::class.java)
|
||||
.observeOn(Schedulers.io())
|
||||
.subscribe({
|
||||
// catch only events from iobCobCalculatorPluginHistory
|
||||
if (it.cause is EventCustomCalculationFinished) {
|
||||
updateGUI("EventAutosensCalculationFinished", bgOnly = true)
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventIobCalculationProgress::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ overview_iobcalculationprogess?.text = it.progress }, fabricPrivacy::logException)
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventRefreshOverview::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
if (it.now) {
|
||||
updateGUI("EventRefreshOverview", bgOnly = false)
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
)
|
||||
if (start == 0L) {
|
||||
// set start of current day
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
runCalculation("onResume")
|
||||
} else {
|
||||
updateGUI("onResume", bgOnly = false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putInt("rangeToDisplay", rangeToDisplay)
|
||||
outState.putLong("start", start)
|
||||
|
||||
}
|
||||
|
||||
private fun prepareGraphsIfNeeded(numOfGraphs: Int) {
|
||||
synchronized(graphLock) {
|
||||
if (numOfGraphs != secondaryGraphs.size - 1) {
|
||||
//aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
|
||||
// rebuild needed
|
||||
secondaryGraphs.clear()
|
||||
secondaryGraphsLabel.clear()
|
||||
history_iobgraph.removeAllViews()
|
||||
for (i in 1 until numOfGraphs) {
|
||||
val relativeLayout = RelativeLayout(this)
|
||||
relativeLayout.layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
||||
val graph = GraphView(this)
|
||||
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, resourceHelper.dpToPx(15), 0, resourceHelper.dpToPx(10)) }
|
||||
graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
|
||||
graph.gridLabelRenderer?.reloadStyles()
|
||||
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
|
||||
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
graph.gridLabelRenderer?.numVerticalLabels = 3
|
||||
graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
|
||||
relativeLayout.addView(graph)
|
||||
|
||||
val label = TextView(this)
|
||||
val layoutParams = RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(resourceHelper.dpToPx(30), resourceHelper.dpToPx(25), 0, 0) }
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP)
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
|
||||
label.layoutParams = layoutParams
|
||||
relativeLayout.addView(label)
|
||||
secondaryGraphsLabel.add(label)
|
||||
|
||||
history_iobgraph.addView(relativeLayout)
|
||||
secondaryGraphs.add(graph)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runCalculation(from: String) {
|
||||
lifecycleScope.launch(Dispatchers.Default) {
|
||||
treatmentsPluginHistory.initializeData(start - T.hours(8).msecs())
|
||||
val end = start + T.hours(rangeToDisplay.toLong()).msecs()
|
||||
iobCobCalculatorPluginHistory.stopCalculation(from)
|
||||
iobCobCalculatorPluginHistory.clearCache()
|
||||
iobCobCalculatorPluginHistory.runCalculation(from, end, true, false, eventCustomCalculationFinished)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateGUI(from: String, bgOnly: Boolean) {
|
||||
val menuChartSettings = overviewMenus.setting
|
||||
prepareGraphsIfNeeded(menuChartSettings.size)
|
||||
aapsLogger.debug(LTag.UI, "updateGUI from: $from")
|
||||
val pump = activePlugin.activePump
|
||||
val profile = profileFunction.getProfile()
|
||||
|
||||
val lowLine = defaultValueHelper.determineLowLine()
|
||||
val highLine = defaultValueHelper.determineHighLine()
|
||||
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
historybrowse_noprofile?.visibility = (profile == null).toVisibility()
|
||||
profile ?: return@launch
|
||||
|
||||
historybrowse_bggraph ?: return@launch
|
||||
historybrowse_date?.text = dateUtil.dateAndTimeString(start)
|
||||
historybrowse_zoom?.text = rangeToDisplay.toString()
|
||||
val graphData = GraphData(injector, historybrowse_bggraph, iobCobCalculatorPluginHistory, treatmentsPluginHistory)
|
||||
val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
|
||||
|
||||
// do preparation in different thread
|
||||
withContext(Dispatchers.Default) {
|
||||
val fromTime: Long = start + T.secs(100).msecs()
|
||||
val toTime: Long = start + T.hours(rangeToDisplay.toLong()).msecs() + T.secs(100).msecs()
|
||||
aapsLogger.debug(LTag.UI, "Period: " + dateUtil.dateAndTimeString(fromTime) + " - " + dateUtil.dateAndTimeString(toTime))
|
||||
val pointer = System.currentTimeMillis()
|
||||
|
||||
// **** In range Area ****
|
||||
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine)
|
||||
|
||||
// **** BG ****
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
graphData.formatAxis(fromTime, toTime)
|
||||
|
||||
// add target line
|
||||
graphData.addTargetLine(fromTime, toTime, profile, null)
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(pointer)
|
||||
|
||||
if (!bgOnly) {
|
||||
// Treatments
|
||||
graphData.addTreatments(fromTime, toTime)
|
||||
if (menuChartSettings[0][OverviewMenus.CharType.ACT.ordinal])
|
||||
graphData.addActivity(fromTime, toTime, false, 0.8)
|
||||
|
||||
// add basal data
|
||||
if (pump.pumpDescription.isTempBasalCapable && menuChartSettings[0][OverviewMenus.CharType.BAS.ordinal]) {
|
||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2)
|
||||
}
|
||||
// ------------------ 2nd graph
|
||||
synchronized(graphLock) {
|
||||
for (g in 0 until secondaryGraphs.size) {
|
||||
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobCalculatorPluginHistory, treatmentsPluginHistory)
|
||||
var useIobForScale = false
|
||||
var useCobForScale = false
|
||||
var useDevForScale = false
|
||||
var useRatioForScale = false
|
||||
var useDSForScale = false
|
||||
var useIAForScale = false
|
||||
var useABSForScale = false
|
||||
when {
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
|
||||
}
|
||||
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, toTime, useIobForScale, 1.0, menuChartSettings[g + 1][OverviewMenus.CharType.PRE.ordinal])
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, toTime, useCobForScale, if (useCobForScale) 1.0 else 0.5)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, toTime, useIAForScale, 0.8)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, toTime, useABSForScale, 1.0)
|
||||
if (menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1.0)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime)
|
||||
secondGraphData.addNowLine(pointer)
|
||||
secondaryGraphsData.add(secondGraphData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// finally enforce drawing of graphs in UI thread
|
||||
graphData.performUpdate()
|
||||
if (!bgOnly)
|
||||
synchronized(graphLock) {
|
||||
for (g in 0 until secondaryGraphs.size) {
|
||||
secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1)
|
||||
secondaryGraphs[g].visibility = (!bgOnly && (
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.COB.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ACT.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.ABS.ordinal] ||
|
||||
menuChartSettings[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
|
||||
)).toVisibility()
|
||||
secondaryGraphsData[g].performUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
package info.nightscout.androidaps.historyBrowser
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class IobCobCalculatorPluginHistory @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
rxBus: RxBusWrapper,
|
||||
sp: SP,
|
||||
resourceHelper: ResourceHelper,
|
||||
profileFunction: ProfileFunction,
|
||||
activePlugin: ActivePluginProvider,
|
||||
treatmentsPluginHistory: TreatmentsPluginHistory,
|
||||
sensitivityOref1Plugin: SensitivityOref1Plugin,
|
||||
sensitivityAAPSPlugin: SensitivityAAPSPlugin,
|
||||
sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin,
|
||||
fabricPrivacy: FabricPrivacy,
|
||||
dateUtil: DateUtil
|
||||
) : IobCobCalculatorPlugin(injector, aapsLogger, rxBus, sp, resourceHelper, profileFunction,
|
||||
activePlugin, treatmentsPluginHistory, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil) {
|
||||
|
||||
override fun onStart() { // do not attach to rxbus
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
package info.nightscout.androidaps.historyBrowser
|
||||
|
||||
import android.content.Context
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||
import info.nightscout.androidaps.plugins.general.nsclient.UploadQueue
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentService
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class TreatmentsPluginHistory @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
rxBus: RxBusWrapper,
|
||||
resourceHelper: ResourceHelper,
|
||||
context: Context,
|
||||
sp: SP,
|
||||
profileFunction: ProfileFunction,
|
||||
activePlugin: ActivePluginProvider,
|
||||
nsUpload: NSUpload,
|
||||
fabricPrivacy: FabricPrivacy,
|
||||
dateUtil: DateUtil,
|
||||
uploadQueue: UploadQueue
|
||||
) : TreatmentsPlugin(injector, aapsLogger, rxBus, resourceHelper, context, sp, profileFunction, activePlugin, nsUpload, fabricPrivacy, dateUtil, uploadQueue) {
|
||||
|
||||
init {
|
||||
onStart()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
service = TreatmentService(injector)
|
||||
initializeData(range())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.aps.events
|
||||
|
||||
import info.nightscout.androidaps.events.Event
|
||||
|
||||
class EventLoopInvoked : Event()
|
|
@ -1,63 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.aps.logger;
|
||||
|
||||
import org.mozilla.javascript.ScriptableObject;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import info.nightscout.androidaps.db.StaticInjector;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
|
||||
/**
|
||||
* Created by adrian on 15/10/17.
|
||||
*/
|
||||
|
||||
|
||||
public class LoggerCallback extends ScriptableObject {
|
||||
|
||||
@Inject
|
||||
AAPSLogger aapsLogger;
|
||||
|
||||
private static StringBuffer errorBuffer = new StringBuffer();
|
||||
private static StringBuffer logBuffer = new StringBuffer();
|
||||
|
||||
|
||||
public LoggerCallback() {
|
||||
//empty constructor needed for Rhino
|
||||
errorBuffer = new StringBuffer();
|
||||
logBuffer = new StringBuffer();
|
||||
StaticInjector.Companion.getInstance().androidInjector().inject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return "LoggerCallback";
|
||||
}
|
||||
|
||||
public void jsConstructor() {
|
||||
//empty constructor on JS site; could work as setter
|
||||
}
|
||||
|
||||
public void jsFunction_log(Object obj1) {
|
||||
aapsLogger.debug(LTag.APS, obj1.toString().trim());
|
||||
logBuffer.append(obj1.toString());
|
||||
}
|
||||
|
||||
public void jsFunction_error(Object obj1) {
|
||||
aapsLogger.error(LTag.APS, obj1.toString().trim());
|
||||
errorBuffer.append(obj1.toString());
|
||||
}
|
||||
|
||||
|
||||
public static String getScriptDebug() {
|
||||
String ret = "";
|
||||
if (errorBuffer.length() > 0) {
|
||||
ret += "e:\n" + errorBuffer.toString();
|
||||
}
|
||||
if (ret.length() > 0 && logBuffer.length() > 0) ret += '\n';
|
||||
if (logBuffer.length() > 0) {
|
||||
ret += "d:\n" + logBuffer.toString();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package info.nightscout.androidaps.plugins.aps.logger
|
||||
|
||||
import info.nightscout.androidaps.di.StaticInjector
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import org.mozilla.javascript.ScriptableObject
|
||||
import javax.inject.Inject
|
||||
|
||||
@Suppress("unused", "FunctionName")
|
||||
class LoggerCallback : ScriptableObject() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
||||
override fun getClassName(): String = "LoggerCallback"
|
||||
|
||||
fun jsConstructor() {
|
||||
//empty constructor on JS site; could work as setter
|
||||
}
|
||||
|
||||
fun jsFunction_log(obj1: Any) {
|
||||
aapsLogger.debug(LTag.APS, obj1.toString().trim { it <= ' ' })
|
||||
logBuffer.append(obj1.toString())
|
||||
}
|
||||
|
||||
fun jsFunction_error(obj1: Any) {
|
||||
aapsLogger.error(LTag.APS, obj1.toString().trim { it <= ' ' })
|
||||
errorBuffer.append(obj1.toString())
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private var errorBuffer = StringBuffer()
|
||||
private var logBuffer = StringBuffer()
|
||||
val scriptDebug: String
|
||||
get() {
|
||||
var ret = ""
|
||||
if (errorBuffer.isNotEmpty()) {
|
||||
ret += """
|
||||
e:
|
||||
$errorBuffer
|
||||
""".trimIndent()
|
||||
}
|
||||
if (ret.isNotEmpty() && logBuffer.isNotEmpty()) ret += '\n'
|
||||
if (logBuffer.isNotEmpty()) {
|
||||
ret += """
|
||||
d:
|
||||
$logBuffer
|
||||
""".trimIndent()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
//empty constructor needed for Rhino
|
||||
errorBuffer = StringBuffer()
|
||||
logBuffer = StringBuffer()
|
||||
@Suppress("DEPRECATION")
|
||||
StaticInjector.Companion.getInstance().androidInjector().inject(this)
|
||||
}
|
||||
}
|
|
@ -3,13 +3,15 @@ package info.nightscout.androidaps.plugins.aps.loop
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import dagger.android.DaggerBroadcastReceiver
|
||||
import info.nightscout.androidaps.interfaces.Loop
|
||||
import javax.inject.Inject
|
||||
|
||||
class CarbSuggestionReceiver : DaggerBroadcastReceiver() {
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var loop: Loop
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
super.onReceive(context, intent)
|
||||
val duration = intent.getIntExtra("ignoreDuration", 5)
|
||||
loopPlugin.disableCarbSuggestions(duration)
|
||||
loop.disableCarbSuggestions(duration)
|
||||
}
|
||||
}
|
|
@ -6,44 +6,54 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.databinding.LoopFragmentBinding
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.interfaces.Loop
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopSetLastRunGui
|
||||
import info.nightscout.androidaps.plugins.aps.loop.events.EventLoopUpdateGui
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.extensions.plusAssign
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.loop_fragment.*
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import javax.inject.Inject
|
||||
|
||||
class LoopFragment : DaggerFragment() {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var loop: Loop
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
private var _binding: LoopFragmentBinding? = 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? {
|
||||
return inflater.inflate(R.layout.loop_fragment, container, false)
|
||||
savedInstanceState: Bundle?): View {
|
||||
_binding = LoopFragmentBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
loop_run.setOnClickListener {
|
||||
loop_lastrun.text = resourceHelper.gs(R.string.executing)
|
||||
Thread { loopPlugin.invoke("Loop button", true) }.start()
|
||||
binding.run.setOnClickListener {
|
||||
binding.lastrun.text = rh.gs(R.string.executing)
|
||||
Thread { loop.invoke("Loop button", true) }.start()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,18 +62,18 @@ class LoopFragment : DaggerFragment() {
|
|||
super.onResume()
|
||||
disposable += rxBus
|
||||
.toObservable(EventLoopUpdateGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
updateGUI()
|
||||
}, { fabricPrivacy.logException(it) })
|
||||
}, fabricPrivacy::logException)
|
||||
|
||||
disposable += rxBus
|
||||
.toObservable(EventLoopSetLastRunGui::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.observeOn(aapsSchedulers.main)
|
||||
.subscribe({
|
||||
clearGUI()
|
||||
loop_lastrun?.text = it.text
|
||||
}, { fabricPrivacy.logException(it) })
|
||||
binding.lastrun.text = it.text
|
||||
}, fabricPrivacy::logException)
|
||||
|
||||
updateGUI()
|
||||
sp.putBoolean(R.string.key_objectiveuseloop, true)
|
||||
|
@ -76,22 +86,27 @@ class LoopFragment : DaggerFragment() {
|
|||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateGUI() {
|
||||
if (loop_request == null) return
|
||||
loopPlugin.lastRun?.let {
|
||||
loop_request?.text = it.request?.toSpanned() ?: ""
|
||||
loop_constraintsprocessed?.text = it.constraintsProcessed?.toSpanned() ?: ""
|
||||
loop_source?.text = it.source ?: ""
|
||||
loop_lastrun?.text = dateUtil.dateAndTimeString(it.lastAPSRun)
|
||||
?: ""
|
||||
loop_smbrequest_time?.text = dateUtil.dateAndTimeAndSecondsString(it.lastSMBRequest)
|
||||
loop_smbexecution_time?.text = dateUtil.dateAndTimeAndSecondsString(it.lastSMBEnact)
|
||||
loop_tbrrequest_time?.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
|
||||
loop_tbrexecution_time?.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
loop_tbrsetbypump?.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
||||
@Synchronized
|
||||
fun updateGUI() {
|
||||
if (_binding == null) return
|
||||
loop.lastRun?.let {
|
||||
binding.request.text = it.request?.toSpanned() ?: ""
|
||||
binding.constraintsprocessed.text = it.constraintsProcessed?.toSpanned() ?: ""
|
||||
binding.source.text = it.source ?: ""
|
||||
binding.lastrun.text = dateUtil.dateAndTimeString(it.lastAPSRun)
|
||||
binding.smbrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastSMBRequest)
|
||||
binding.smbexecutionTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastSMBEnact)
|
||||
binding.tbrrequestTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBRRequest)
|
||||
binding.tbrexecutionTime.text = dateUtil.dateAndTimeAndSecondsString(it.lastTBREnact)
|
||||
|
||||
binding.tbrsetbypump.text = it.tbrSetByPump?.let { tbrSetByPump -> HtmlHelper.fromHtml(tbrSetByPump.toHtml()) }
|
||||
?: ""
|
||||
loop_smbsetbypump?.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
||||
binding.smbsetbypump.text = it.smbSetByPump?.let { smbSetByPump -> HtmlHelper.fromHtml(smbSetByPump.toHtml()) }
|
||||
?: ""
|
||||
|
||||
val constraints =
|
||||
|
@ -101,22 +116,22 @@ class LoopFragment : DaggerFragment() {
|
|||
constraintsProcessed.smbConstraint?.let { smbConstraint -> allConstraints.copyReasons(smbConstraint) }
|
||||
allConstraints.getMostLimitedReasons(aapsLogger)
|
||||
} ?: ""
|
||||
loop_constraints?.text = constraints
|
||||
binding.constraints.text = constraints
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun clearGUI() {
|
||||
loop_request?.text = ""
|
||||
loop_constraints?.text = ""
|
||||
loop_constraintsprocessed?.text = ""
|
||||
loop_source?.text = ""
|
||||
loop_lastrun?.text = ""
|
||||
loop_smbrequest_time?.text = ""
|
||||
loop_smbexecution_time?.text = ""
|
||||
loop_tbrrequest_time?.text = ""
|
||||
loop_tbrexecution_time?.text = ""
|
||||
loop_tbrsetbypump?.text = ""
|
||||
loop_smbsetbypump?.text = ""
|
||||
binding.request.text = ""
|
||||
binding.constraints.text = ""
|
||||
binding.constraintsprocessed.text = ""
|
||||
binding.source.text = ""
|
||||
binding.lastrun.text = ""
|
||||
binding.smbrequestTime.text = ""
|
||||
binding.smbexecutionTime.text = ""
|
||||
binding.tbrrequestTime.text = ""
|
||||
binding.tbrexecutionTime.text = ""
|
||||
binding.tbrsetbypump.text = ""
|
||||
binding.smbsetbypump.text = ""
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue