package info.nightscout.androidaps.plugins.Overview;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.ContextMenu;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.ValueDependentColor;
import com.jjoe64.graphview.series.BarGraphSeries;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.jjoe64.graphview.series.PointsGraphSeries;
import com.squareup.otto.Subscribe;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.TempBasal;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.db.Treatment;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventNewBG;
import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.events.EventTreatmentChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
import info.nightscout.androidaps.plugins.Objectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.CalibrationDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog;
import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog;
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
import info.nightscout.androidaps.plugins.Overview.graphExtensions.TimeAsXAxisLabelFormatter;
import info.nightscout.androidaps.plugins.SourceXdrip.SourceXdripPlugin;
import info.nightscout.androidaps.plugins.TempTargetRange.TempTargetRangePlugin;
import info.nightscout.androidaps.plugins.TempTargetRange.events.EventTempTargetRangeChange;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile;
import info.nightscout.utils.BolusWizard;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.Round;
import info.nightscout.utils.SP;
import info.nightscout.utils.ToastUtils;
public class OverviewFragment extends Fragment {
private static Logger log = LoggerFactory.getLogger(OverviewFragment.class);
private static OverviewPlugin overviewPlugin = new OverviewPlugin();
public static OverviewPlugin getPlugin() {
return overviewPlugin;
}
TextView bgView;
TextView arrowView;
TextView timeAgoView;
TextView deltaView;
TextView avgdeltaView;
TextView runningTempView;
TextView baseBasalView;
LinearLayout basalLayout;
TextView activeProfileView;
TextView iobView;
TextView apsModeView;
TextView tempTargetView;
TextView pumpStatusView;
LinearLayout loopStatusLayout;
LinearLayout pumpStatusLayout;
GraphView bgGraph;
CheckBox showPredictionView;
RecyclerView notificationsView;
LinearLayoutManager llm;
LinearLayout cancelTempLayout;
LinearLayout acceptTempLayout;
Button cancelTempButton;
Button treatmentButton;
Button wizardButton;
Button calibrationButton;
Button acceptTempButton;
Button quickWizardButton;
Handler sLoopHandler = new Handler();
Runnable sRefreshLoop = null;
private static Handler sHandler;
private static HandlerThread sHandlerThread;
public OverviewFragment() {
super();
if (sHandlerThread == null) {
sHandlerThread = new HandlerThread(OverviewFragment.class.getSimpleName());
sHandlerThread.start();
sHandler = new Handler(sHandlerThread.getLooper());
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview_fragment, container, false);
bgView = (TextView) view.findViewById(R.id.overview_bg);
arrowView = (TextView) view.findViewById(R.id.overview_arrow);
timeAgoView = (TextView) view.findViewById(R.id.overview_timeago);
deltaView = (TextView) view.findViewById(R.id.overview_delta);
avgdeltaView = (TextView) view.findViewById(R.id.overview_avgdelta);
runningTempView = (TextView) view.findViewById(R.id.overview_runningtemp);
baseBasalView = (TextView) view.findViewById(R.id.overview_basebasal);
basalLayout = (LinearLayout) view.findViewById(R.id.overview_basallayout);
activeProfileView = (TextView) view.findViewById(R.id.overview_activeprofile);
pumpStatusView = (TextView) view.findViewById(R.id.overview_pumpstatus);
loopStatusLayout = (LinearLayout) view.findViewById(R.id.overview_looplayout);
pumpStatusLayout = (LinearLayout) view.findViewById(R.id.overview_pumpstatuslayout);
iobView = (TextView) view.findViewById(R.id.overview_iob);
apsModeView = (TextView) view.findViewById(R.id.overview_apsmode);
tempTargetView = (TextView) view.findViewById(R.id.overview_temptarget);
bgGraph = (GraphView) view.findViewById(R.id.overview_bggraph);
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
treatmentButton = (Button) view.findViewById(R.id.overview_treatment);
wizardButton = (Button) view.findViewById(R.id.overview_wizard);
cancelTempButton = (Button) view.findViewById(R.id.overview_canceltemp);
cancelTempLayout = (LinearLayout) view.findViewById(R.id.overview_canceltemplayout);
acceptTempButton = (Button) view.findViewById(R.id.overview_accepttempbutton);
acceptTempLayout = (LinearLayout) view.findViewById(R.id.overview_accepttemplayout);
quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizard);
calibrationButton = (Button) view.findViewById(R.id.overview_calibration);
showPredictionView = (CheckBox) view.findViewById(R.id.overview_showprediction);
notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications);
notificationsView.setHasFixedSize(true);
llm = new LinearLayoutManager(view.getContext());
notificationsView.setLayoutManager(llm);
showPredictionView.setChecked(SP.getBoolean("showprediction", false));
showPredictionView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("showprediction", showPredictionView.isChecked());
editor.apply();
updateGUI();
}
});
treatmentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
NewTreatmentDialog treatmentDialogFragment = new NewTreatmentDialog();
treatmentDialogFragment.show(manager, "TreatmentDialog");
}
});
wizardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
WizardDialog wizardDialog = new WizardDialog();
wizardDialog.show(manager, "WizardDialog");
}
});
quickWizardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
processQuickWizard();
}
});
cancelTempButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final PumpInterface pump = MainApp.getConfigBuilder();
if (pump.isTempBasalInProgress()) {
sHandler.post(new Runnable() {
@Override
public void run() {
pump.cancelTempBasal();
MainApp.bus().post(new EventTempBasalChange());
Answers.getInstance().logCustom(new CustomEvent("CancelTemp"));
}
});
}
}
});
calibrationButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
CalibrationDialog calibrationDialog = new CalibrationDialog();
calibrationDialog.show(manager, "CalibrationDialog");
}
});
acceptTempButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ConfigBuilderPlugin.getActiveLoop().invoke("Accept temp button", false);
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (finalLastRun != null && finalLastRun.lastAPSRun != null && finalLastRun.constraintsProcessed.changeRequested) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(getContext().getString(R.string.confirmation));
builder.setMessage(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
builder.setPositiveButton(getContext().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
sHandler.post(new Runnable() {
@Override
public void run() {
hideTempRecommendation();
PumpEnactResult applyResult = MainApp.getConfigBuilder().applyAPSRequest(finalLastRun.constraintsProcessed);
if (applyResult.enacted) {
finalLastRun.setByPump = applyResult;
finalLastRun.lastEnact = new Date();
finalLastRun.lastOpenModeAccept = new Date();
MainApp.getConfigBuilder().uploadDeviceStatus();
ObjectivesPlugin objectivesPlugin = (ObjectivesPlugin) MainApp.getSpecificPlugin(ObjectivesPlugin.class);
if (objectivesPlugin != null) {
objectivesPlugin.manualEnacts++;
objectivesPlugin.saveProgress();
}
}
updateGUIIfVisible();
}
});
Answers.getInstance().logCustom(new CustomEvent("AcceptTemp"));
}
});
builder.setNegativeButton(getContext().getString(R.string.cancel), null);
builder.show();
}
updateGUI();
}
});
pumpStatusView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (MainApp.getConfigBuilder().isSuspended() || !MainApp.getConfigBuilder().isInitialized())
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.getConfigBuilder().refreshDataFromPump("RefreshClicked");
}
});
}
});
updateGUI();
return view;
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
if (activeloop == null)
return;
menu.setHeaderTitle(MainApp.sResources.getString(R.string.loop));
if (activeloop.isEnabled(PluginBase.LOOP)) {
menu.add(MainApp.sResources.getString(R.string.disableloop));
if (!activeloop.isSuspended()) {
menu.add(MainApp.sResources.getString(R.string.suspendloopfor1h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor2h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor3h));
menu.add(MainApp.sResources.getString(R.string.suspendloopfor10h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor30m));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor1h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor2h));
menu.add(MainApp.sResources.getString(R.string.disconnectpumpfor3h));
} else {
menu.add(MainApp.sResources.getString(R.string.resume));
}
}
if (!activeloop.isEnabled(PluginBase.LOOP))
menu.add(MainApp.sResources.getString(R.string.enableloop));
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
if (item.getTitle().equals(MainApp.sResources.getString(R.string.disableloop))) {
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
activeloop.setFragmentVisible(PluginBase.LOOP, false);
MainApp.getConfigBuilder().storeSettings();
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
activeloop.setFragmentVisible(PluginBase.LOOP, true);
MainApp.getConfigBuilder().storeSettings();
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) {
activeloop.suspendTo(0L);
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.bus().post(new EventRefreshGui(false));
PumpEnactResult result = MainApp.getConfigBuilder().cancelTempBasal();
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) {
activeloop.suspendTo(new Date().getTime() + 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) {
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) {
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) {
activeloop.suspendTo(new Date().getTime() + 10 * 60L * 60 * 1000);
MainApp.bus().post(new EventRefreshGui(false));
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
activeloop.suspendTo(new Date().getTime() + 30L * 60 * 1000);
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 30);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
MainApp.bus().post(new EventRefreshGui(false));
}
});
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
activeloop.suspendTo(new Date().getTime() + 1 * 60L * 60 * 1000);
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.bus().post(new EventRefreshGui(false));
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.bus().post(new EventRefreshGui(false));
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 2 * 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
return true;
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
sHandler.post(new Runnable() {
@Override
public void run() {
MainApp.bus().post(new EventRefreshGui(false));
PumpEnactResult result = MainApp.getConfigBuilder().setTempBasalAbsolute(0d, 3 * 60);
if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.sResources.getString(R.string.tempbasaldeliveryerror));
}
}
});
return true;
}
return super.onContextItemSelected(item);
}
void processQuickWizard() {
final BgReading actualBg = GlucoseStatus.actualBg();
if (MainApp.getConfigBuilder() == null || ConfigBuilderPlugin.getActiveProfile() == null) // app not initialized yet
return;
final NSProfile profile = ConfigBuilderPlugin.getActiveProfile().getProfile();
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && actualBg != null) {
quickWizardButton.setVisibility(View.VISIBLE);
String text = MainApp.sResources.getString(R.string.bolus) + ": " + quickWizardEntry.buttonText();
BolusWizard wizard = new BolusWizard();
wizard.doCalc(profile.getDefaultProfile(), quickWizardEntry.carbs(), actualBg.valueToUnits(profile.getUnits()), 0d, true, true);
final JSONObject boluscalcJSON = new JSONObject();
try {
boluscalcJSON.put("eventTime", DateUtil.toISOString(new Date()));
boluscalcJSON.put("targetBGLow", wizard.targetBGLow);
boluscalcJSON.put("targetBGHigh", wizard.targetBGHigh);
boluscalcJSON.put("isf", wizard.sens);
boluscalcJSON.put("ic", wizard.ic);
boluscalcJSON.put("iob", -(wizard.insulingFromBolusIOB + wizard.insulingFromBasalsIOB));
boluscalcJSON.put("bolusiobused", true);
boluscalcJSON.put("basaliobused", true);
boluscalcJSON.put("bg", actualBg.valueToUnits(profile.getUnits()));
boluscalcJSON.put("insulinbg", wizard.insulinFromBG);
boluscalcJSON.put("insulinbgused", true);
boluscalcJSON.put("bgdiff", wizard.bgDiff);
boluscalcJSON.put("insulincarbs", wizard.insulinFromCarbs);
boluscalcJSON.put("carbs", quickWizardEntry.carbs());
boluscalcJSON.put("othercorrection", 0d);
boluscalcJSON.put("insulin", wizard.calculatedTotalInsulin);
} catch (JSONException e) {
e.printStackTrace();
}
if (wizard.calculatedTotalInsulin > 0d && quickWizardEntry.carbs() > 0d) {
DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
String confirmMessage = getString(R.string.entertreatmentquestion);
Double insulinAfterConstraints = MainApp.getConfigBuilder().applyBolusConstraints(wizard.calculatedTotalInsulin);
Integer carbsAfterConstraints = MainApp.getConfigBuilder().applyCarbsConstraints(quickWizardEntry.carbs());
confirmMessage += "\n" + getString(R.string.bolus) + ": " + formatNumber2decimalplaces.format(insulinAfterConstraints) + "U";
confirmMessage += "\n" + getString(R.string.carbs) + ": " + carbsAfterConstraints + "g";
if (insulinAfterConstraints - wizard.calculatedTotalInsulin != 0 || carbsAfterConstraints != quickWizardEntry.carbs()) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.treatmentdeliveryerror));
builder.setMessage(getString(R.string.constraints_violation) + "\n" + getString(R.string.changeyourinput));
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
builder.show();
return;
}
final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Integer finalCarbsAfterConstraints = carbsAfterConstraints;
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.confirmation));
builder.setMessage(confirmMessage);
builder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (finalInsulinAfterConstraints > 0 || finalCarbsAfterConstraints > 0) {
final ConfigBuilderPlugin pump = MainApp.getConfigBuilder();
sHandler.post(new Runnable() {
@Override
public void run() {
PumpEnactResult result = pump.deliverTreatmentFromBolusWizard(
getContext(),
finalInsulinAfterConstraints,
finalCarbsAfterConstraints,
actualBg.valueToUnits(profile.getUnits()),
"Manual",
0,
boluscalcJSON
);
if (!result.success) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle(MainApp.sResources.getString(R.string.treatmentdeliveryerror));
builder.setMessage(result.comment);
builder.setPositiveButton(MainApp.sResources.getString(R.string.ok), null);
builder.show();
}
}
});
Answers.getInstance().logCustom(new CustomEvent("QuickWizard"));
}
}
});
builder.setNegativeButton(getString(R.string.cancel), null);
builder.show();
}
}
}
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
sLoopHandler.removeCallbacksAndMessages(null);
unregisterForContextMenu(apsModeView);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
sRefreshLoop = new Runnable() {
@Override
public void run() {
updateGUIIfVisible();
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
}
};
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
registerForContextMenu(apsModeView);
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventPreferenceChange ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventRefreshGui ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventTreatmentChange ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventNewBG ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventNewOpenLoopNotification ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventNewBasalProfile ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventTempTargetRangeChange ev) {
updateGUIIfVisible();
}
@Subscribe
public void onStatusEvent(final EventNewNotification n) {
updateNotifications();
}
@Subscribe
public void onStatusEvent(final EventDismissNotification n) {
updateNotifications();
}
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged s) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updatePumpStatus(s.textStatus());
}
});
}
private void hideTempRecommendation() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
acceptTempLayout.setVisibility(View.GONE);
}
});
}
private void updateGUIIfVisible() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
updateGUI();
}
});
}
private void updatePumpStatus(String status) {
PumpInterface pump = MainApp.getConfigBuilder();
if (!status.equals("")) {
pumpStatusView.setText(status);
pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE);
} else {
wizardButton.setVisibility(View.VISIBLE);
treatmentButton.setVisibility(View.VISIBLE);
pumpStatusLayout.setVisibility(View.GONE);
loopStatusLayout.setVisibility(View.VISIBLE);
}
}
@SuppressLint("SetTextI18n")
public void updateGUI() {
updateNotifications();
BgReading actualBG = GlucoseStatus.actualBg();
BgReading lastBG = GlucoseStatus.lastBg();
if (MainApp.getConfigBuilder() == null || MainApp.getConfigBuilder().getActiveProfile() == null || MainApp.getConfigBuilder().getActiveProfile().getProfile() == null) {// app not initialized yet
pumpStatusView.setText(R.string.noprofileset);
pumpStatusLayout.setVisibility(View.VISIBLE);
loopStatusLayout.setVisibility(View.GONE);
return;
} else {
pumpStatusLayout.setVisibility(View.GONE);
loopStatusLayout.setVisibility(View.VISIBLE);
}
PumpInterface pump = MainApp.getConfigBuilder();
// Skip if not initialized yet
if (bgGraph == null)
return;
if (getActivity() == null)
return;
// open loop mode
final LoopPlugin.LastRun finalLastRun = LoopPlugin.lastRun;
if (Config.APS && MainApp.getConfigBuilder().getPumpDescription().isTempBasalCapable) {
apsModeView.setVisibility(View.VISIBLE);
apsModeView.setBackgroundResource(R.drawable.loopmodeborder);
apsModeView.setTextColor(Color.BLACK);
final LoopPlugin activeloop = MainApp.getConfigBuilder().getActiveLoop();
if (activeloop != null && activeloop.isEnabled(activeloop.getType()) && activeloop.isSuspended()) {
apsModeView.setBackgroundResource(R.drawable.loopmodesuspendedborder);
apsModeView.setText(String.format(MainApp.sResources.getString(R.string.loopsuspendedfor), activeloop.minutesToEndOfSuspend()));
apsModeView.setTextColor(Color.WHITE);
} else if (pump.isSuspended()) {
apsModeView.setBackgroundResource(R.drawable.loopmodesuspendedborder);
apsModeView.setText(MainApp.sResources.getString(R.string.pumpsuspended));
apsModeView.setTextColor(Color.WHITE);
} else if (activeloop != null && activeloop.isEnabled(activeloop.getType())) {
if (MainApp.getConfigBuilder().isClosedModeEnabled()) {
apsModeView.setText(MainApp.sResources.getString(R.string.closedloop));
} else {
apsModeView.setText(MainApp.sResources.getString(R.string.openloop));
}
} else {
apsModeView.setBackgroundResource(R.drawable.loopmodedisabledborder);
apsModeView.setText(MainApp.sResources.getString(R.string.disabledloop));
apsModeView.setTextColor(Color.WHITE);
}
} else {
apsModeView.setVisibility(View.GONE);
}
// temp target
NSProfile profile = MainApp.getConfigBuilder().getActiveProfile().getProfile();
TempTargetRangePlugin tempTargetRangePlugin = (TempTargetRangePlugin) MainApp.getSpecificPlugin(TempTargetRangePlugin.class);
if (Config.APS && tempTargetRangePlugin != null && tempTargetRangePlugin.isEnabled(PluginBase.GENERAL)) {
TempTarget tempTarget = tempTargetRangePlugin.getTempTargetInProgress(new Date().getTime());
if (tempTarget != null) {
tempTargetView.setTextColor(Color.BLACK);
tempTargetView.setBackgroundResource(R.drawable.temptargetborder);
tempTargetView.setVisibility(View.VISIBLE);
tempTargetView.setText(NSProfile.toUnitsString(tempTarget.low, NSProfile.fromMgdlToUnits(tempTarget.low, profile.getUnits()), profile.getUnits()) + " - " + NSProfile.toUnitsString(tempTarget.high, NSProfile.fromMgdlToUnits(tempTarget.high, profile.getUnits()), profile.getUnits()));
} else {
Double maxBgDefault = Constants.MAX_BG_DEFAULT_MGDL;
Double minBgDefault = Constants.MIN_BG_DEFAULT_MGDL;
if (!profile.getUnits().equals(Constants.MGDL)) {
maxBgDefault = Constants.MAX_BG_DEFAULT_MMOL;
minBgDefault = Constants.MIN_BG_DEFAULT_MMOL;
}
tempTargetView.setTextColor(Color.WHITE);
tempTargetView.setBackgroundResource(R.drawable.temptargetborderdisabled);
tempTargetView.setText(SP.getDouble("openapsma_min_bg", minBgDefault) + " - " + SP.getDouble("openapsma_max_bg", maxBgDefault));
tempTargetView.setVisibility(View.VISIBLE);
}
} else {
tempTargetView.setVisibility(View.GONE);
}
// **** Temp button ****
boolean showAcceptButton = !MainApp.getConfigBuilder().isClosedModeEnabled(); // Open mode needed
showAcceptButton = showAcceptButton && finalLastRun != null && finalLastRun.lastAPSRun != null; // aps result must exist
showAcceptButton = showAcceptButton && (finalLastRun.lastOpenModeAccept == null || finalLastRun.lastOpenModeAccept.getTime() < finalLastRun.lastAPSRun.getTime()); // never accepted or before last result
showAcceptButton = showAcceptButton && finalLastRun.constraintsProcessed.changeRequested; // change is requested
if (showAcceptButton && pump.isInitialized() && !pump.isSuspended() && ConfigBuilderPlugin.getActiveLoop() != null) {
acceptTempLayout.setVisibility(View.VISIBLE);
acceptTempButton.setText(getContext().getString(R.string.setbasalquestion) + "\n" + finalLastRun.constraintsProcessed);
} else {
acceptTempLayout.setVisibility(View.GONE);
}
// **** Calibration button ****
if (MainApp.getSpecificPlugin(SourceXdripPlugin.class).isEnabled(PluginBase.BGSOURCE) && profile != null && GlucoseStatus.actualBg() != null) {
calibrationButton.setVisibility(View.VISIBLE);
} else {
calibrationButton.setVisibility(View.GONE);
}
TempBasal activeTemp = pump.getTempBasal();
if (pump.isTempBasalInProgress()) {
cancelTempLayout.setVisibility(View.VISIBLE);
cancelTempButton.setText(MainApp.instance().getString(R.string.cancel) + ": " + activeTemp.toString());
runningTempView.setVisibility(View.VISIBLE);
runningTempView.setText(activeTemp.toString());
} else {
cancelTempLayout.setVisibility(View.GONE);
runningTempView.setVisibility(View.GONE);
}
if (pump.getPumpDescription().isTempBasalCapable) {
basalLayout.setVisibility(View.VISIBLE);
baseBasalView.setText(DecimalFormatter.to2Decimal(pump.getBaseBasalRate()) + " U/h");
} else {
basalLayout.setVisibility(View.GONE);
}
if (profile != null && profile.getActiveProfile() != null)
activeProfileView.setText(profile.getActiveProfile());
activeProfileView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = new OptionsToShow(R.id.careportal_profileswitch, R.string.careportal_profileswitch, true, false, false, false, false, false, false, true, false, false);
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch);
newDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
activeProfileView.setLongClickable(true);
tempTargetView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = new OptionsToShow(R.id.careportal_temporarytarget, R.string.careportal_temporarytarget, false, false, false, false, true, false, false, false, false, true);
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget);
newTTDialog.show(getFragmentManager(), "NewNSTreatmentDialog");
return true;
}
});
tempTargetView.setLongClickable(true);
// QuickWizard button
QuickWizard.QuickWizardEntry quickWizardEntry = getPlugin().quickWizard.getActive();
if (quickWizardEntry != null && lastBG != null && pump.isInitialized() && !pump.isSuspended()) {
quickWizardButton.setVisibility(View.VISIBLE);
String text = MainApp.sResources.getString(R.string.bolus) + ": " + quickWizardEntry.buttonText() + " " + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = new BolusWizard();
wizard.doCalc(profile.getDefaultProfile(), quickWizardEntry.carbs(), lastBG.valueToUnits(profile.getUnits()), 0d, true, true);
text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U";
quickWizardButton.setText(text);
if (wizard.calculatedTotalInsulin <= 0)
quickWizardButton.setVisibility(View.GONE);
} else
quickWizardButton.setVisibility(View.GONE);
String units = profile.getUnits();
// **** BG value ****
if (lastBG != null) {
bgView.setText(lastBG.valueToUnitsToString(profile.getUnits()));
arrowView.setText(lastBG.directionToSymbol());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
if (glucoseStatus != null) {
deltaView.setText("Δ " + NSProfile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units);
avgdeltaView.setText("øΔ15m: " + NSProfile.toUnitsString(glucoseStatus.short_avgdelta, glucoseStatus.short_avgdelta * Constants.MGDL_TO_MMOLL, units) +
" øΔ40m: " + NSProfile.toUnitsString(glucoseStatus.long_avgdelta, glucoseStatus.long_avgdelta * Constants.MGDL_TO_MMOLL, units));
} else {
deltaView.setText("Δ " + MainApp.sResources.getString(R.string.notavailable));
avgdeltaView.setText("");
}
BgReading.units = profile.getUnits();
} else
return;
Integer flag = bgView.getPaintFlags();
if (actualBG == null) {
flag |= Paint.STRIKE_THRU_TEXT_FLAG;
} else
flag &= ~Paint.STRIKE_THRU_TEXT_FLAG;
bgView.setPaintFlags(flag);
Long agoMsec = new Date().getTime() - lastBG.timeIndex;
int agoMin = (int) (agoMsec / 60d / 1000d);
timeAgoView.setText(String.format(MainApp.sResources.getString(R.string.minago), agoMin));
// iob
ConfigBuilderPlugin.getActiveTreatments().updateTotalIOB();
IobTotal bolusIob = ConfigBuilderPlugin.getActiveTreatments().getLastCalculation().round();
IobTotal basalIob = new IobTotal(new Date().getTime());
if (ConfigBuilderPlugin.getActiveTempBasals() != null) {
ConfigBuilderPlugin.getActiveTempBasals().updateTotalIOB();
basalIob = ConfigBuilderPlugin.getActiveTempBasals().getLastCalculation().round();
}
String iobtext = getString(R.string.treatments_iob_label_string) + " " + DecimalFormatter.to2Decimal(bolusIob.iob + basalIob.basaliob) + "U ("
+ getString(R.string.bolus) + ": " + DecimalFormatter.to2Decimal(bolusIob.iob) + "U "
+ getString(R.string.basal) + ": " + DecimalFormatter.to2Decimal(basalIob.basaliob) + "U)";
iobView.setText(iobtext);
boolean showPrediction = showPredictionView.isChecked() && finalLastRun != null && finalLastRun.constraintsProcessed.getClass().equals(DetermineBasalResultAMA.class);
if (MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class) != null && MainApp.getSpecificPlugin(OpenAPSAMAPlugin.class).isEnabled(PluginBase.APS)) {
showPredictionView.setVisibility(View.VISIBLE);
} else {
showPredictionView.setVisibility(View.GONE);
}
// ****** GRAPH *******
// allign to hours
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(new Date().getTime());
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.add(Calendar.HOUR, 1);
int hoursToFetch;
long toTime;
long fromTime;
long endTime;
if (showPrediction) {
int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - new Date().getTime()) / (60 * 60 * 1000));
predHours = Math.min(2, predHours);
predHours = Math.max(0, predHours);
hoursToFetch = (int) (6 - predHours);
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
endTime = toTime + predHours * 60 * 60 * 1000L;
} else {
hoursToFetch = 6;
toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding
fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
endTime = toTime;
}
Double lowLine = SP.getDouble("low_mark", 0d);
Double highLine = SP.getDouble("high_mark", 0d);
if (lowLine < 1) {
lowLine = NSProfile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units);
}
if (highLine < 1) {
highLine = NSProfile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units);
}
LineGraphSeries<DataPoint> basalsLineSeries = null;
BarGraphSeries<DataPoint> basalsSeries = null;
LineGraphSeries<DataPoint> seriesLow = null;
LineGraphSeries<DataPoint> seriesHigh = null;
LineGraphSeries<DataPoint> seriesNow = null;
PointsGraphSeries<BgReading> seriesInRage = null;
PointsGraphSeries<BgReading> seriesOutOfRange = null;
PointsGraphSeries<BgReading> predSeries = null;
PointsWithLabelGraphSeries<Treatment> seriesTreatments = null;
// remove old data from graph
bgGraph.removeAllSeries();
// **** HIGH and LOW targets graph ****
DataPoint[] lowDataPoints = new DataPoint[]{
new DataPoint(fromTime, lowLine),
new DataPoint(endTime, lowLine)
};
DataPoint[] highDataPoints = new DataPoint[]{
new DataPoint(fromTime, highLine),
new DataPoint(endTime, highLine)
};
bgGraph.addSeries(seriesLow = new LineGraphSeries<DataPoint>(lowDataPoints));
seriesLow.setColor(Color.RED);
bgGraph.addSeries(seriesHigh = new LineGraphSeries<DataPoint>(highDataPoints));
seriesHigh.setColor(Color.RED);
// **** TEMP BASALS graph ****
class BarDataPoint extends DataPoint {
public BarDataPoint(double x, double y, boolean isTempBasal) {
super(x, y);
this.isTempBasal = isTempBasal;
}
public boolean isTempBasal = false;
}
Double maxBasalValueFound = 0d;
long now = new Date().getTime();
if (pump.getPumpDescription().isTempBasalCapable) {
List<BarDataPoint> basalArray = new ArrayList<BarDataPoint>();
List<DataPoint> basalLineArray = new ArrayList<DataPoint>();
double lastBaseBasal = 0;
for (long time = fromTime; time < now; time += 5 * 60 * 1000L) {
TempBasal tb = MainApp.getConfigBuilder().getTempBasal(new Date(time));
double basebasal = profile.getBasal(NSProfile.secondsFromMidnight(new Date(time)));
Double basal = 0d;
if (tb != null)
basalArray.add(new BarDataPoint(time, basal = tb.tempBasalConvertedToAbsolute(new Date(time)), true));
else {
basalArray.add(new BarDataPoint(time, basal = basebasal, false));
}
if (basebasal != lastBaseBasal)
basalLineArray.add(new DataPoint(time, lastBaseBasal));
basalLineArray.add(new DataPoint(time, basebasal));
lastBaseBasal = basebasal;
maxBasalValueFound = Math.max(maxBasalValueFound, basal);
}
BarDataPoint[] basal = new BarDataPoint[basalArray.size()];
basal = basalArray.toArray(basal);
bgGraph.addSeries(basalsSeries = new BarGraphSeries<DataPoint>(basal));
basalsSeries.setValueDependentColor(new ValueDependentColor<DataPoint>() {
@Override
public int get(DataPoint data) {
BarDataPoint point = (BarDataPoint) data;
if (point.isTempBasal) return Color.BLUE;
else return Color.CYAN;
}
});
DataPoint[] basalLine = new DataPoint[basalLineArray.size()];
basalLine = basalLineArray.toArray(basalLine);
bgGraph.addSeries(basalsLineSeries = new LineGraphSeries<DataPoint>(basalLine));
basalsLineSeries.setColor(Color.CYAN);
basalsLineSeries.setDrawDataPoints(false);
basalsLineSeries.setThickness(2);
}
// set manual x bounds to have nice steps
bgGraph.getViewport().setMaxX(endTime);
bgGraph.getViewport().setMinX(fromTime);
bgGraph.getViewport().setXAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setLabelFormatter(new TimeAsXAxisLabelFormatter(getActivity(), "HH"));
bgGraph.getGridLabelRenderer().setNumHorizontalLabels(7); // only 7 because of the space
// **** BG graph ****
List<BgReading> bgReadingsArray = MainApp.getDbHelper().getBgreadingsDataFromTime(fromTime, true);
List<BgReading> inRangeArray = new ArrayList<BgReading>();
List<BgReading> outOfRangeArray = new ArrayList<BgReading>();
if (bgReadingsArray.size() == 0)
return;
Iterator<BgReading> it = bgReadingsArray.iterator();
Double maxBgValue = 0d;
while (it.hasNext()) {
BgReading bg = it.next();
if (bg.value > maxBgValue) maxBgValue = bg.value;
if (bg.valueToUnits(units) < lowLine || bg.valueToUnits(units) > highLine)
outOfRangeArray.add(bg);
else
inRangeArray.add(bg);
}
maxBgValue = NSProfile.fromMgdlToUnits(maxBgValue, units);
maxBgValue = units.equals(Constants.MGDL) ? Round.roundTo(maxBgValue, 40d) + 80 : Round.roundTo(maxBgValue, 2d) + 4;
if (highLine > maxBgValue) maxBgValue = highLine;
Integer numOfHorizLines = units.equals(Constants.MGDL) ? (int) (maxBgValue / 40 + 1) : (int) (maxBgValue / 2 + 1);
BgReading[] inRange = new BgReading[inRangeArray.size()];
BgReading[] outOfRange = new BgReading[outOfRangeArray.size()];
inRange = inRangeArray.toArray(inRange);
outOfRange = outOfRangeArray.toArray(outOfRange);
if (inRange.length > 0) {
bgGraph.addSeries(seriesInRage = new PointsGraphSeries<BgReading>(inRange));
seriesInRage.setShape(PointsGraphSeries.Shape.POINT);
seriesInRage.setSize(5);
seriesInRage.setColor(Color.GREEN);
}
if (outOfRange.length > 0) {
bgGraph.addSeries(seriesOutOfRange = new PointsGraphSeries<BgReading>(outOfRange));
seriesOutOfRange.setShape(PointsGraphSeries.Shape.POINT);
seriesOutOfRange.setSize(5);
seriesOutOfRange.setColor(Color.RED);
}
if (showPrediction) {
DetermineBasalResultAMA amaResult = (DetermineBasalResultAMA) finalLastRun.constraintsProcessed;
List<BgReading> predArray = amaResult.getPredictions();
BgReading[] pred = new BgReading[predArray.size()];
pred = predArray.toArray(pred);
if (pred.length > 0) {
bgGraph.addSeries(predSeries = new PointsGraphSeries<BgReading>(pred));
predSeries.setShape(PointsGraphSeries.Shape.POINT);
predSeries.setSize(4);
predSeries.setColor(Color.MAGENTA);
}
}
// **** NOW line ****
DataPoint[] nowPoints = new DataPoint[]{
new DataPoint(now, 0),
new DataPoint(now, maxBgValue)
};
bgGraph.addSeries(seriesNow = new LineGraphSeries<DataPoint>(nowPoints));
seriesNow.setColor(Color.GREEN);
seriesNow.setDrawDataPoints(false);
//seriesNow.setThickness(1);
// custom paint to make a dotted line
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setPathEffect(new DashPathEffect(new float[]{10, 20}, 0));
paint.setColor(Color.WHITE);
seriesNow.setCustomPaint(paint);
// Treatments
List<Treatment> treatments = MainApp.getConfigBuilder().getActiveTreatments().getTreatments();
List<Treatment> filteredTreatments = new ArrayList<Treatment>();
for (int tx = 0; tx < treatments.size(); tx++) {
Treatment t = treatments.get(tx);
if (t.getTimeIndex() < fromTime || t.getTimeIndex() > now) continue;
t.setYValue(bgReadingsArray);
filteredTreatments.add(t);
}
Treatment[] treatmentsArray = new Treatment[filteredTreatments.size()];
treatmentsArray = filteredTreatments.toArray(treatmentsArray);
if (treatmentsArray.length > 0) {
bgGraph.addSeries(seriesTreatments = new PointsWithLabelGraphSeries<Treatment>(treatmentsArray));
seriesTreatments.setShape(PointsWithLabelGraphSeries.Shape.TRIANGLE);
seriesTreatments.setSize(10);
seriesTreatments.setColor(Color.CYAN);
}
// set manual y bounds to have nice steps
bgGraph.getViewport().setMaxY(maxBgValue);
bgGraph.getViewport().setMinY(0);
bgGraph.getViewport().setYAxisBoundsManual(true);
bgGraph.getGridLabelRenderer().setNumVerticalLabels(numOfHorizLines);
// set second scale
if (pump.getPumpDescription().isTempBasalCapable) {
bgGraph.getSecondScale().addSeries(basalsSeries);
bgGraph.getSecondScale().addSeries(basalsLineSeries);
bgGraph.getSecondScale().setMinY(0);
bgGraph.getSecondScale().setMaxY(maxBgValue / lowLine * maxBasalValueFound * 1.2d);
bgGraph.getGridLabelRenderer().setVerticalLabelsSecondScaleColor(ContextCompat.getColor(MainApp.instance(), R.color.background_material_dark)); // same color as backround = hide
}
//updatePumpStatus(null);
}
//Notifications
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.NotificationsViewHolder> {
List<Notification> notificationsList;
RecyclerViewAdapter(List<Notification> notificationsList) {
this.notificationsList = notificationsList;
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.overview_notification_item, viewGroup, false);
NotificationsViewHolder notificationsViewHolder = new NotificationsViewHolder(v);
return notificationsViewHolder;
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
Notification notification = notificationsList.get(position);
holder.dismiss.setTag(notification);
holder.text.setText(notification.text);
holder.time.setText(DateUtil.timeString(notification.date));
if (notification.level == Notification.URGENT)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationUrgent));
else if (notification.level == Notification.NORMAL)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationNormal));
else if (notification.level == Notification.LOW)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationLow));
else if (notification.level == Notification.INFO)
holder.cv.setBackgroundColor(ContextCompat.getColor(MainApp.instance(), R.color.notificationInfo));
}
@Override
public int getItemCount() {
return notificationsList.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public static class NotificationsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CardView cv;
TextView time;
TextView text;
Button dismiss;
NotificationsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.notification_cardview);
time = (TextView) itemView.findViewById(R.id.notification_time);
text = (TextView) itemView.findViewById(R.id.notification_text);
dismiss = (Button) itemView.findViewById(R.id.notification_dismiss);
dismiss.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Notification notification = (Notification) v.getTag();
switch (v.getId()) {
case R.id.notification_dismiss:
MainApp.bus().post(new EventDismissNotification(notification.id));
break;
}
}
}
}
void updateNotifications() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
NotificationStore nstore = getPlugin().notificationStore;
nstore.removeExpired();
if (nstore.store.size() > 0) {
RecyclerViewAdapter adapter = new RecyclerViewAdapter(nstore.store);
notificationsView.setAdapter(adapter);
notificationsView.setVisibility(View.VISIBLE);
} else {
notificationsView.setVisibility(View.GONE);
}
}
});
}
}