From abfb832a10b06b03a5cdca052363adba38f588dc Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 5 Dec 2016 15:20:44 +0100 Subject: [PATCH] basic notification functionality --- .idea/misc.xml | 2 +- .../plugins/Overview/Notification.java | 20 ++++ .../plugins/Overview/NotificationStore.java | 74 ++++++++++++ .../plugins/Overview/OverviewFragment.java | 112 ++++++++++++++++++ .../plugins/Overview/OverviewPlugin.java | 17 +++ .../events/EventDismissNotification.java | 14 +++ .../Overview/events/EventNewNotification.java | 15 +++ app/src/main/res/layout/overview_fragment.xml | 7 ++ .../res/layout/overview_notification_item.xml | 45 +++++++ app/src/main/res/values/colors.xml | 5 + wear/wear.iml | 20 ++-- 11 files changed, 322 insertions(+), 9 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventDismissNotification.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventNewNotification.java create mode 100644 app/src/main/res/layout/overview_notification_item.xml diff --git a/.idea/misc.xml b/.idea/misc.xml index fbb68289f4..5d19981032 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -37,7 +37,7 @@ - + diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java new file mode 100644 index 0000000000..abf7858db4 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Notification.java @@ -0,0 +1,20 @@ +package info.nightscout.androidaps.plugins.Overview; + +import java.util.Date; + +/** + * Created by mike on 03.12.2016. + */ + +public class Notification { + public static final int URGENT = 0; + public static final int NORMAL = 1; + public static final int LOW = 2; + public static final int INFO = 3; + + public int id; + Date date; + String text; + Date validTo = new Date(0); + int level; +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java new file mode 100644 index 0000000000..5750d19dbd --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/NotificationStore.java @@ -0,0 +1,74 @@ +package info.nightscout.androidaps.plugins.Overview; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; + + +/** + * Created by mike on 03.12.2016. + */ + +public class NotificationStore { + public List store = new ArrayList(); + + public NotificationStore() { + Notification sample = new Notification(); + sample.id = 1; + sample.date = new Date(); + sample.text = "Sample text"; + sample.level = Notification.URGENT; + sample.validTo = new Date(new Date().getTime() + 3 * 60 * 1000L); + add(sample); + Notification sample1 = new Notification(); + sample1.id = 2; + sample1.date = new Date(); + sample1.text = "Sample text 1"; + sample1.level = Notification.INFO; + sample1.validTo = new Date(new Date().getTime() + 60 * 60 * 1000L); + add(sample1); + } + + public class NotificationComparator implements Comparator { + @Override + public int compare(Notification o1, Notification o2) { + return o1.level - o2.level; + } + } + + public Notification get(int index) { + return store.get(index); + } + + public void add(Notification n) { + for (int i = 0; i < store.size(); i++) { + if (get(i).id == n.id) { + get(i).date = n.date; + get(i).validTo = n.validTo; + return; + } + } + store.add(n); + Collections.sort(store, new NotificationComparator()); + } + + public void remove(int id) { + for (int i = 0; i < store.size(); i++) { + if (get(i).id == id) { + store.remove(i); + return; + } + } + } + + public void removeExpired() { + for (int i = 0; i < store.size(); i++) { + Notification n = get(i); + if (n.validTo.getTime() != 0 && n.validTo.getTime() < new Date().getTime()) { + store.remove(i); + } + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index 1d9100f216..7291c80bd8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -14,6 +14,9 @@ import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; 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.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.View; @@ -35,6 +38,7 @@ import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.text.DateFormat; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Calendar; @@ -69,6 +73,8 @@ import info.nightscout.androidaps.plugins.OpenAPSMA.IobTotal; import info.nightscout.androidaps.plugins.Overview.Dialogs.NewTreatmentDialog; import info.nightscout.androidaps.plugins.Overview.Dialogs.WizardDialog; import info.nightscout.androidaps.plugins.Overview.GraphSeriesExtension.PointsWithLabelGraphSeries; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; import info.nightscout.client.data.NSProfile; import info.nightscout.utils.BolusWizard; import info.nightscout.utils.DateUtil; @@ -98,6 +104,9 @@ public class OverviewFragment extends Fragment { TextView apsModeView; GraphView bgGraph; + RecyclerView notificationsView; + LinearLayoutManager llm; + LinearLayout cancelTempLayout; LinearLayout acceptTempLayout; LinearLayout quickWizardLayout; @@ -148,6 +157,11 @@ public class OverviewFragment extends Fragment { quickWizardButton = (Button) view.findViewById(R.id.overview_quickwizard); quickWizardLayout = (LinearLayout) view.findViewById(R.id.overview_quickwizardlayout); + notificationsView = (RecyclerView) view.findViewById(R.id.overview_notifications); + notificationsView.setHasFixedSize(true); + llm = new LinearLayoutManager(view.getContext()); + notificationsView.setLayoutManager(llm); + treatmentButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { @@ -383,6 +397,12 @@ public class OverviewFragment extends Fragment { @Subscribe public void onStatusEvent(final EventNewBasalProfile ev) { updateGUIIfVisible(); } + @Subscribe + public void onStatusEvent(final EventNewNotification n) { updateNotifications(); } + + @Subscribe + public void onStatusEvent(final EventDismissNotification n) { updateNotifications(); } + private void hideTempRecommendation() { Activity activity = getActivity(); if (activity != null) @@ -407,6 +427,7 @@ public class OverviewFragment extends Fragment { @SuppressLint("SetTextI18n") public void updateGUI() { + updateNotifications(); BgReading actualBG = MainApp.getDbHelper().actualBg(); BgReading lastBG = MainApp.getDbHelper().lastBg(); if (MainApp.getConfigBuilder() == null || MainApp.getConfigBuilder().getActiveProfile() == null) // app not initialized yet @@ -758,4 +779,95 @@ public class OverviewFragment extends Fragment { } + //Notifications + public static class RecyclerViewAdapter extends RecyclerView.Adapter { + + List notificationsList; + + RecyclerViewAdapter(List 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) { + DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT); + Notification notification = notificationsList.get(position); + holder.dismiss.setTag(notification); + holder.text.setText(notification.text); + holder.time.setText(df.format(notification.date)); + if (notification.level == Notification.URGENT) + holder.cv.setBackgroundColor(MainApp.instance().getResources().getColor(R.color.notificationUrgent)); + else if (notification.level == Notification.NORMAL) + holder.cv.setBackgroundColor(MainApp.instance().getResources().getColor(R.color.notificationNormal)); + else if (notification.level == Notification.LOW) + holder.cv.setBackgroundColor(MainApp.instance().getResources().getColor(R.color.notificationLow)); + else if (notification.level == Notification.INFO) + holder.cv.setBackgroundColor(MainApp.instance().getResources().getColor(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); + } + } + }); + } + + + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java index 86dfa1532f..164238a57a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewPlugin.java @@ -3,12 +3,16 @@ package info.nightscout.androidaps.plugins.Overview; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import com.squareup.otto.Subscribe; + import org.json.JSONArray; import org.json.JSONException; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification; +import info.nightscout.androidaps.plugins.Overview.events.EventNewNotification; /** * Created by mike on 05.08.2016. @@ -20,6 +24,8 @@ public class OverviewPlugin implements PluginBase { public QuickWizard quickWizard = new QuickWizard(); + public NotificationStore notificationStore = new NotificationStore(); + public OverviewPlugin() { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); String storedData = preferences.getString("QuickWizard", "[]"); @@ -28,6 +34,7 @@ public class OverviewPlugin implements PluginBase { } catch (JSONException e) { e.printStackTrace(); } + MainApp.bus().register(this); } @Override @@ -71,4 +78,14 @@ public class OverviewPlugin implements PluginBase { } + @Subscribe + public void onStatusEvent(final EventNewNotification n) { + notificationStore.add(n.notification); + } + + @Subscribe + public void onStatusEvent(final EventDismissNotification n) { + notificationStore.remove(n.id); + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventDismissNotification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventDismissNotification.java new file mode 100644 index 0000000000..f2414e2a4e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventDismissNotification.java @@ -0,0 +1,14 @@ +package info.nightscout.androidaps.plugins.Overview.events; + +/** + * Created by mike on 03.12.2016. + */ + +public class EventDismissNotification { + public int id; + + public EventDismissNotification(int did) { + id = did; + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventNewNotification.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventNewNotification.java new file mode 100644 index 0000000000..8a80019f3e --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/events/EventNewNotification.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.Overview.events; + +import info.nightscout.androidaps.plugins.Overview.Notification; + +/** + * Created by mike on 03.12.2016. + */ + +public class EventNewNotification { + public Notification notification; + + public EventNewNotification(Notification n) { + notification = n; + } +} diff --git a/app/src/main/res/layout/overview_fragment.xml b/app/src/main/res/layout/overview_fragment.xml index 34e05a9f60..1f2f066b71 100644 --- a/app/src/main/res/layout/overview_fragment.xml +++ b/app/src/main/res/layout/overview_fragment.xml @@ -13,6 +13,13 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + + + + + + + + + + + + + +