Commit 7bed0279 authored by Robert Hitt's avatar Robert Hitt

Merge branch 'master' into 'material-spec'

# Conflicts:
#   app/src/main/res/layout-land/fragment_notification_dialog.xml
#   app/src/main/res/layout/fragment_notification_dialog.xml
parents 9628597a 3482956e
Pipeline #866 failed with stages
in 16 seconds
......@@ -3,6 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application
android:name=".MyApplication"
android:allowBackup="true"
......@@ -37,7 +39,13 @@
<receiver android:name=".util.NotificationReceiver"
android:process=":remote" >
</receiver>
<receiver android:name=".util.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name=".util.NotificationService"
......
......@@ -10,13 +10,14 @@ public class Facility extends RealmObject {
public Facility(String name, String location, MainSchedule mainSchedule,
RealmList<SpecialSchedule> specialSchedules, boolean isOpen,
boolean isFavorited) {
boolean isFavorited, String statusDuration) {
mName = name;
mLocation = location;
mMainSchedule = mainSchedule;
mSpecialSchedules = specialSchedules;
this.isOpen = isOpen;
this.isFavorited = isFavorited;
this.statusDuration = statusDuration;
}
public Facility() {
......@@ -37,6 +38,15 @@ public class Facility extends RealmObject {
private boolean isOpen;
private boolean isFavorited;
private String statusDuration;
public String getStatusDuration() {
return statusDuration;
}
public void setStatusDuration(String statusDuration) {
this.statusDuration = statusDuration;
}
public RealmList<SpecialSchedule> getSpecialSchedules() {
return mSpecialSchedules;
......
package srct.whatsopen.model;
public class NotificationSettings {
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
public class NotificationSettings extends RealmObject {
public NotificationSettings() {
}
public NotificationSettings(boolean opening, boolean closing, boolean interval_on, boolean interval_15, boolean interval_30, boolean interval_hour) {
public NotificationSettings(String name, boolean opening, boolean closing, boolean interval_on, boolean interval_15, boolean interval_30, boolean interval_hour) {
this.name = name;
this.opening = opening;
this.closing = closing;
this.interval_on = interval_on;
......@@ -15,6 +19,9 @@ public class NotificationSettings {
this.interval_hour = interval_hour;
}
@PrimaryKey
public String name;
public boolean opening;
public boolean closing;
public boolean interval_on;
......
......@@ -12,6 +12,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import io.realm.Realm;
import io.realm.RealmList;
......@@ -67,113 +68,68 @@ public class FacilityPresenter {
realm.close();
}
// Finds the next time the facility closes or opens and returns it
public String getStatusDuration(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = getActiveSchedule(facility, now);
if(openTimesList.size() == 0)
return "No open time on schedule";
// Parses the schedule into an HTML string
// Kind of a hacky approach
public String getSchedule(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = getActiveSchedule(facility, now);
int currentDay = (5 + now.get(Calendar.DAY_OF_WEEK)) % 7;
String durationMessage;
if(facility.isOpen()) {
if(facilityDoesNotClose(openTimesList.first())) {
return "Open 24/7";
}
if(openTimesList.size() == 0)
return "No schedule available";
String closingTime = getCurrentEndTime(openTimesList, currentDay);
closingTime = parseTo12HourTime(closingTime);
durationMessage = "Closes at " + closingTime;
if(facilityDoesNotClose(openTimesList))
return "This facility is always open";
return durationMessage;
}
StringBuilder scheduleString = new StringBuilder();
boolean first = true;
for(OpenTimes o : openTimesList) {
if(first)
first = false;
else
scheduleString.append("<br/>");
// Check if the facility opens later today
if(openTimesContains(openTimesList, currentDay)) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
try {
Date currentTime = sdf.parse(sdf.format(now.getTime()));
Date startTime = sdf.parse(getCurrentStartTime(openTimesList, currentDay));
// the current day's schedule should be highlighted
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
scheduleString.append("<strong>");
if(currentTime.compareTo(startTime) < 0) {
String openingTime = getCurrentStartTime(openTimesList, currentDay);
openingTime = parseTo12HourTime(openingTime);
scheduleString.append("<b>" + parseIntToDay(o.getStartDay()) + "</b>: ");
scheduleString.append(parseTo12HourTime(o.getStartTime()));
scheduleString.append(" - ");
scheduleString.append(parseTo12HourTime(o.getEndTime()));
return "Opens today at " + openingTime;
}
} catch (ParseException pe) {
pe.printStackTrace();
return "";
}
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
scheduleString.append("</strong>");
}
// Else return the opening time of the next day
int nextDay = findNextDay(openTimesList, currentDay);
String nextDayStr = parseIntToDay(nextDay);
String openingTime = getCurrentStartTime(openTimesList, nextDay);
openingTime = parseTo12HourTime(openingTime);
durationMessage = "Opens next on " + nextDayStr + " at " + openingTime;
return durationMessage;
return scheduleString.toString();
}
private boolean openTimesContains(RealmList<OpenTimes> openTimesList, int currentDay) {
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
return true;
}
return false;
}
public static boolean facilityDoesNotClose(List<OpenTimes> openTimesList) {
boolean doesNotClose = false;
// Returns the next open day in the list of OpenTimes
private int findNextDay(RealmList<OpenTimes> openTimesList, int current) {
int nextDay = openTimesList.first().getStartDay();
int counter = 0;
for(OpenTimes o : openTimesList) {
if(o.getStartDay() > current) {
nextDay = o.getStartDay();
break;
if(o.getStartTime().equals("00:00:00") && o.getEndTime().equals("23:59:59")
|| o.getEndTime().equals("00:00:00")) {
doesNotClose = true;
}
}
return nextDay;
}
// Returns the end time for the current day
private String getCurrentEndTime(RealmList<OpenTimes> openTimesList, int currentDay) {
String endTime = "";
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
endTime = o.getEndTime();
// check to make sure the facility is open every day of the week
// so, if the start day is 0 and the end day is 6, 6 - 0 + 1 == 7
counter += (o.getEndDay() - o.getStartDay()) + 1;
}
return endTime;
}
// Returns the end time for the current day
private String getCurrentStartTime(RealmList<OpenTimes> openTimesList, int currentDay) {
String startTime = "";
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
startTime = o.getStartTime();
if(counter != 7) {
doesNotClose = false;
}
return startTime;
}
// Currently only works if the Facility has one OpenTimes with
// startDay == 0 and endDay == 6. Should work if the Facility has 7
// OpenTimes
// TODO: fix
private boolean facilityDoesNotClose(OpenTimes openTimes) {
return (openTimes.getStartDay() == 0 && openTimes.getEndDay() == 6 &&
openTimes.getStartTime().equals("00:00:00") &&
openTimes.getEndTime().equals("23:59:59"));
return doesNotClose;
}
// Parses 24 hour formatted time String to 12 hour formatted time String
private String parseTo12HourTime(String time) {
public static String parseTo12HourTime(String time) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
final Date date = sdf.parse(time);
......@@ -185,7 +141,7 @@ public class FacilityPresenter {
}
// Parses an integer to a String of the day of the week
private String parseIntToDay(int day) {
public static String parseIntToDay(int day) {
switch(day) {
case 0:
return "Monday";
......@@ -206,42 +162,6 @@ public class FacilityPresenter {
}
}
// Parses the schedule into an HTML string
// Kind of a hacky approach
public String getSchedule(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = getActiveSchedule(facility, now);
int currentDay = (5 + now.get(Calendar.DAY_OF_WEEK)) % 7;
if(openTimesList.size() == 0)
return "No schedule available";
if(facilityDoesNotClose(openTimesList.first()))
return "This facility is always open";
StringBuilder scheduleString = new StringBuilder();
boolean first = true;
for(OpenTimes o : openTimesList) {
if(first)
first = false;
else
scheduleString.append("<br/>");
// the current day's schedule should be highlighted
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
scheduleString.append("<strong>");
scheduleString.append("<b>" + parseIntToDay(o.getStartDay()) + "</b>: ");
scheduleString.append(parseTo12HourTime(o.getStartTime()));
scheduleString.append(" - ");
scheduleString.append(parseTo12HourTime(o.getEndTime()));
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
scheduleString.append("</strong>");
}
return scheduleString.toString();
}
// Returns the active schedule given the current date
private RealmList<OpenTimes> getActiveSchedule(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = facility.getMainSchedule().getOpenTimesList();
......
......@@ -83,6 +83,7 @@ public class MainPresenter {
// Query SharedReferences for each Facility's favorite status. defaults to false
facility.setFavorited(pref.getBoolean(facility.getName()+"FavoriteStatus", false));
facility.setOpen(getOpenStatus(facility, Calendar.getInstance()));
facility.setStatusDuration(getStatusDuration(facility, Calendar.getInstance()));
}
return facilities;
......@@ -125,20 +126,23 @@ public class MainPresenter {
final String name = facility.getName();
realm.executeTransactionAsync((bgRealm) -> {
RealmResults<Facility> results = realm.where(Facility.class).equalTo("mName", name)
RealmResults<Facility> results = bgRealm.where(Facility.class).equalTo("mName", name)
.findAll();
results.deleteAllFromRealm();
});
realm.close();
}
// Sets the open status of each facility in the Realm instance
// Sets the open status and status duration of each facility in the Realm instance
private void updateOpenStatus() {
Realm realm = Realm.getDefaultInstance();
realm.executeTransactionAsync(bgRealm -> {
List<Facility> facilities = bgRealm.where(Facility.class).findAll();
for(Facility f : facilities) {
f.setOpen(getOpenStatus(f, Calendar.getInstance()));
f.setStatusDuration(getStatusDuration(f, Calendar.getInstance()));
}
}, null, null);
realm.close();
......@@ -161,6 +165,13 @@ public class MainPresenter {
if(currentOpenTimes == null)
return false;
// for some reason in the Api this signifies a facility that's open 24/7, sometimes
// praying for that api v2
if(currentOpenTimes.getStartTime().equals("00:00:00")
&& currentOpenTimes.getEndTime().equals("00:00:00")) {
return true;
}
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
try {
......@@ -179,6 +190,104 @@ public class MainPresenter {
}
}
// Finds the next time the facility closes or opens and returns it
public String getStatusDuration(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = getActiveSchedule(facility, now);
if(openTimesList == null)
return "";
if(openTimesList.size() == 0)
return "No open time on schedule";
int currentDay = (5 + now.get(Calendar.DAY_OF_WEEK)) % 7;
String durationMessage;
if(facility.isOpen()) {
if(FacilityPresenter.facilityDoesNotClose(openTimesList)) {
return "Open 24/7";
}
String closingTime = getCurrentEndTime(openTimesList, currentDay);
closingTime = FacilityPresenter.parseTo12HourTime(closingTime);
durationMessage = "Closes at " + closingTime;
return durationMessage;
}
// Check if the facility opens later today
if(openTimesContains(openTimesList, currentDay)) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
try {
Date currentTime = sdf.parse(sdf.format(now.getTime()));
Date startTime = sdf.parse(getCurrentStartTime(openTimesList, currentDay));
if(currentTime.compareTo(startTime) < 0) {
String openingTime = getCurrentStartTime(openTimesList, currentDay);
openingTime = FacilityPresenter.parseTo12HourTime(openingTime);
return "Opens today at " + openingTime;
}
} catch (ParseException pe) {
pe.printStackTrace();
return "";
}
}
// Else return the opening time of the next day
int nextDay = findNextDay(openTimesList, currentDay);
String nextDayStr = FacilityPresenter.parseIntToDay(nextDay);
String openingTime = getCurrentStartTime(openTimesList, nextDay);
openingTime = FacilityPresenter.parseTo12HourTime(openingTime);
durationMessage = "Opens next on " + nextDayStr + " at " + openingTime;
return durationMessage;
}
private boolean openTimesContains(RealmList<OpenTimes> openTimesList, int currentDay) {
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
return true;
}
return false;
}
// Returns the next open day in the list of OpenTimes
private int findNextDay(RealmList<OpenTimes> openTimesList, int current) {
int nextDay = openTimesList.first().getStartDay();
for(OpenTimes o : openTimesList) {
if(o.getStartDay() > current) {
nextDay = o.getStartDay();
break;
}
}
return nextDay;
}
// Returns the end time for the current day
private String getCurrentEndTime(RealmList<OpenTimes> openTimesList, int currentDay) {
String endTime = "";
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
endTime = o.getEndTime();
}
return endTime;
}
// Returns the end time for the current day
private String getCurrentStartTime(RealmList<OpenTimes> openTimesList, int currentDay) {
String startTime = "";
for(OpenTimes o : openTimesList) {
if(o.getStartDay() <= currentDay && o.getEndDay() >= currentDay)
startTime = o.getStartTime();
}
return startTime;
}
// Returns the active schedule given the current date
private RealmList<OpenTimes> getActiveSchedule(Facility facility, Calendar now) {
RealmList<OpenTimes> openTimesList = facility.getMainSchedule().getOpenTimesList();
......
package srct.whatsopen.util;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import io.realm.Realm;
import io.realm.RealmResults;
import srct.whatsopen.model.NotificationSettings;
import srct.whatsopen.presenters.NotificationPresenter;
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Resets Notifications on boot
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Realm realm = Realm.getDefaultInstance();
RealmResults<NotificationSettings> results = realm.where(NotificationSettings.class)
.findAll();
for(NotificationSettings n : results) {
if(n != null) {
NotificationPresenter.createAlarmsForFacility(context, n);
}
}
realm.close();
}
}
}
package srct.whatsopen.util;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;
public class NotificationReceiver extends BroadcastReceiver {
public class NotificationReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
......@@ -14,6 +14,7 @@ public class NotificationReceiver extends BroadcastReceiver {
i.putExtra("title", intent.getStringExtra("title"));
i.putExtra("text", intent.getStringExtra("text"));
context.startService(i);
//context.startService(i);
startWakefulService(context, i);
}
}
......@@ -5,6 +5,7 @@ import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.WakefulBroadcastReceiver;
import srct.whatsopen.R;
......@@ -31,5 +32,6 @@ public class NotificationService extends IntentService {
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id, builder.build());
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}
}
......@@ -25,6 +25,7 @@ import butterknife.OnClick;
import io.realm.Realm;
import srct.whatsopen.R;
import srct.whatsopen.model.Facility;
import srct.whatsopen.model.NotificationSettings;
import srct.whatsopen.views.FacilityView;
import srct.whatsopen.presenters.FacilityPresenter;
import srct.whatsopen.views.fragments.NotificationDialogFragment;
......@@ -146,8 +147,7 @@ public class DetailActivity extends AppCompatActivity implements FacilityView,
String statusText = mFacility.isOpen() ? "Open" : "Closed";
openStatusTextView.setText(statusText);
openDurationTextView.setText(mPresenter.getStatusDuration(mFacility,
Calendar.getInstance()));
openDurationTextView.setText(mFacility.getStatusDuration());
locationTextView.setText(mFacility.getLocation());
......@@ -157,9 +157,10 @@ public class DetailActivity extends AppCompatActivity implements FacilityView,
// Sets the notification button text to edit if a Notification exists
private void setNotificationStatus() {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
Set<String> notificationSettings = pref.getStringSet(mFacility.getName()
+ "NotificationSettings", null);
Realm realm = Realm.getDefaultInstance();
NotificationSettings notificationSettings = realm.where(NotificationSettings.class)
.equalTo("name", mFacility.getName()).findFirst();
realm.close();
if (notificationSettings != null) {
inEditMode = true;
......
......@@ -121,7 +121,7 @@ public class FacilityListAdapter extends
mPresenter = new FacilityPresenter();
mPresenter.attachView(this);
duration = mPresenter.getStatusDuration(data, Calendar.getInstance());
duration = data.getStatusDuration();
durationTextView.setText(duration);
}
......
......@@ -81,6 +81,11 @@ public class NotificationDialogFragment extends DialogFragment implements Notifi
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
// Changes the Notification button text in DetailActivity
NotificationDialogListener listener = (NotificationDialogListener) getActivity();
if(listener != null) {
listener.onSetNotification();
}
}
@Nullable
......@@ -107,15 +112,11 @@ public class NotificationDialogFragment extends DialogFragment implements Notifi
@OnClick(R.id.save_button)
public void onSave() {
mPresenter.saveNotifications(mName, inEditMode, new NotificationSettings(
mPresenter.saveNotifications(inEditMode, new NotificationSettings(mName,
typeOpeningCheckBox.isChecked(), typeClosingCheckBox.isChecked(),
intervalOnCheckBox.isChecked(), interval15CheckBox.isChecked(),
interval30CheckBox.isChecked(), intervalHourCheckBox.isChecked()
));
// Changes the Notification button text in DetailActivity
NotificationDialogListener listener = (NotificationDialogListener) getActivity();
listener.onSetNotification();
}
@OnClick(R.id.cancel_button)
......@@ -127,10 +128,6 @@ public class NotificationDialogFragment extends DialogFragment implements Notifi
@OnClick(R.id.remove_button)
public void onRemove() {
mPresenter.removeNotifications(mName, true);
// Changes the Notification button text in DetailActivity
NotificationDialogListener listener = (NotificationDialogListener) getActivity();
listener.onSetNotification();
}
@Override
......
......@@ -131,4 +131,4 @@
</RelativeLayout>
</LinearLayout>
</ScrollView>
</ScrollView>
\ No newline at end of file
......@@ -38,51 +38,12 @@ public class FacilityPresenterUnitTest {
"2017-01-09", "2017-01-15");
mFacility = new Facility("Chef's Table at Brooklyn Fare", "Whitetop Hall",
mainSchedule, new RealmList<>(), false, true);
mainSchedule, new RealmList<>(), false, true, "");
now = Calendar.getInstance();
now.set(2017, 0, 9, 13, 0); // Monday, 1/9/2017, 13:00:00
}
@Test
public void testFacilityMessageOpensToday() {
// Set date
now.set(2017, 0, 9, 10, 0); // Monday, 1/9/2017, 10:00:00
String statusDuration = mPresenter.getStatusDuration(mFacility, now);
assertEquals("Opens today at 11:00 AM", statusDuration);
}
@Test
public void testFacilityMessageOpensNotToday() {
// Set date
now.set(2017, 0, 11, 10, 0); // Wednesday, 1/11/2017, 10:00:00
String statusDuration = mPresenter.getStatusDuration(mFacility, now);
assertEquals("Opens next on Monday at 11:00 AM", statusDuration);
}
@Test
public void testFacilityMessageCloses() {
// Set date
now.set(2017, 0, 9, 13, 0); // Monday, 1/9/2017, 13:00:00