Skip to content

Commit

Permalink
plusonelabs#356 Make widget entry date and position of the widget ent…
Browse files Browse the repository at this point in the history
…ry on a timeline independent from an event start and end/due dates. Introduce special timeline positions like "End of today" in order to implement Tasks positioning and sorting as per plusonelabs#356 (comment)
  • Loading branch information
yvolk committed Dec 28, 2019
1 parent 0472066 commit f367a1c
Show file tree
Hide file tree
Showing 18 changed files with 255 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ private void playAtOneTime(QueryResultsStorage inputs, DateTime now, int entries
factory.getWidgetEntries().size());
if (entriesWithoutLastExpected > 0) {
CalendarEntry birthday = (CalendarEntry) factory.getWidgetEntries().get(1);
assertEquals(9, birthday.getStartDate().dayOfMonth().get());
assertEquals(0, birthday.getStartDate().hourOfDay().get());
assertEquals(0, birthday.getStartDate().minuteOfHour().get());
assertEquals(0, birthday.getStartDate().millisOfDay().get());
assertEquals(9, birthday.entryDate.dayOfMonth().get());
assertEquals(0, birthday.entryDate.hourOfDay().get());
assertEquals(0, birthday.entryDate.minuteOfHour().get());
assertEquals(0, birthday.entryDate.millisOfDay().get());
assertEquals(true, birthday.isAllDay());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ public void testInsidePeriod() throws IOException, JSONException {
WidgetEntry entry = factory.getWidgetEntries().get(ind);
String logMsg = method + "; " + String.format("%02d ", ind) + entry.toString();
Log.v(TAG, logMsg);
if (entry.getStartDay().isBefore(today)) {
if (entry.getEntryDay().isBefore(today)) {
fail("Is present before today " + logMsg);
}
if (entry.getStartDay().isAfter(endOfRangeTime)) {
if (entry.getEntryDay().isAfter(endOfRangeTime)) {
fail("After end of range " + logMsg);
}
int dayOfEntry = entry.getStartDay().getDayOfYear();
int dayOfEntry = entry.getEntryDay().getDayOfYear();
if (entry instanceof DayHeader) {
if (dayOfHeaderPrev == 0) {
if (entry.getStartDate().withTimeAtStartOfDay().isAfter(today)) {
if (entry.entryDate.withTimeAtStartOfDay().isAfter(today)) {
fail("No today's header " + logMsg);
}
} else {
Expand All @@ -68,7 +68,7 @@ public void testInsidePeriod() throws IOException, JSONException {
assertEquals(LastEntry.LastEntryType.LAST, ((LastEntry) entry).type);
} else {
if (dayOfEventEntryPrev == 0) {
if (entry.getStartDate().withTimeAtStartOfDay().isAfter(today)) {
if (entry.entryDate.withTimeAtStartOfDay().isAfter(today)) {
fail("Today not filled " + logMsg);
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.andstatus.todoagenda.widget.CalendarEntry;
import org.andstatus.todoagenda.widget.WidgetEntry;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
Expand All @@ -29,9 +30,10 @@ public class MultidayEventTest extends BaseWidgetTest {
*/
@Test
public void testEventWhichCarryOverToTheNextDay() {
DateTime today = DateUtil.now(provider.getSettings().getTimeZone()).withTimeAtStartOfDay();
DateTimeZone timeZone = provider.getSettings().getTimeZone();
DateTime today = DateUtil.now(timeZone).withTimeAtStartOfDay();
CalendarEvent event = new CalendarEvent(provider.getContext(), provider.getWidgetId(),
provider.getSettings().getTimeZone(), false);
timeZone, false);
event.setEventSource(provider.getFirstActiveEventSource());
event.setEventId(++eventId);
event.setTitle("Event that carry over to the next day, show as ending midnight");
Expand All @@ -58,15 +60,15 @@ public void testEventWhichCarryOverToTheNextDay() {
assertTrue("Is Part of Multi Day Event", entry1.isPartOfMultiDayEvent());
assertTrue("Is start of Multi Day Event", entry1.isStartOfMultiDayEvent());
assertFalse("Is not an end of Multi Day Event", entry1.isEndOfMultiDayEvent());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry1.getStartDate());
assertEquals("Event entry end time is next midnight", today.plusDays(1), entry1.getEndDate());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry1.entryDate);
assertEquals("Entry end time should be the same as Event end time", event.getEndDate(), entry1.getEndDate());

assertNotNull(entry2);
assertFalse("Is not active event", entry2.getEvent().isActive());
assertTrue("Is Part of Multi Day Event", entry2.isPartOfMultiDayEvent());
assertFalse("Is not start of Multi Day Event", entry2.isStartOfMultiDayEvent());
assertTrue("Is end of Multi Day Event", entry2.isEndOfMultiDayEvent());
assertEquals("Start Time of tomorrow's entry is midnight", today.plusDays(1), entry2.getStartDate());
assertEquals("Start Time of tomorrow's entry is midnight", today.plusDays(1), entry2.entryDate);
assertEquals("Tomorrow event entry end time is the same as for the event", entry2.getEvent().getEndDate(), entry2.getEndDate());
}

Expand All @@ -92,7 +94,7 @@ public void testThreeDaysEvent() {

private void assertSundayEntryAt(CalendarEvent event, DateTime sunday, DateTime currentDateTime) {
CalendarEntry entry1 = getSundayEntryAt(event, currentDateTime);
assertEquals(sunday, entry1.getStartDate());
assertEquals(sunday, entry1.entryDate);
assertEquals(event.getEndDate(), entry1.getEndDate());
assertEquals(event.getTitle(), entry1.getTitle());
String timeString = entry1.getEventTimeString();
Expand All @@ -111,7 +113,7 @@ private CalendarEntry getSundayEntryAt(CalendarEvent event, DateTime currentDate
for (WidgetEntry item : factory.getWidgetEntries()) {
if (item instanceof CalendarEntry) {
CalendarEntry entry = (CalendarEntry) item;
if (entry.getStartDate().getDayOfMonth() == 20) {
if (entry.entryDate.getDayOfMonth() == 20) {
assertNull(sundayEntry);
sundayEntry = entry;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void testTodaysOngoingEvent() {
assertNotNull(entry);
assertTrue("Is active event", entry.getEvent().isActive());
assertFalse("Is not part of Multi Day Event", entry.isPartOfMultiDayEvent());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry.getStartDate());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry.entryDate);
assertEquals("End Time didn't change for today's event", event.getEndDate(), entry.getEndDate());
}

Expand Down Expand Up @@ -79,7 +79,7 @@ public void testYesterdaysOngoingEvent() {
assertTrue("Is Part of Multi Day Event", entry.isPartOfMultiDayEvent());
assertFalse("Is not start of Multi Day Event", entry.isStartOfMultiDayEvent());
assertTrue("Is end of Multi Day Event", entry.isEndOfMultiDayEvent());
assertEquals("Yesterday's event entry start time is midnight", today, entry.getStartDate());
assertEquals("Yesterday's event entry start time is midnight", today, entry.entryDate);
assertEquals("End Time didn't change for yesterday's event", event.getEndDate(), entry.getEndDate());
}

Expand Down Expand Up @@ -110,8 +110,8 @@ public void testEventWhichCarryOverToTheNextDay() {
assertTrue("Is Part of Multi Day Event", entry.isPartOfMultiDayEvent());
assertTrue("Is start of Multi Day Event", entry.isStartOfMultiDayEvent());
assertFalse("Is not an end of Multi Day Event", entry.isEndOfMultiDayEvent());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry.getStartDate());
assertEquals("Event entry end time is next midnight", today.plusDays(1), entry.getEndDate());
assertEquals("Start Time didn't change for today's event", event.getStartDate(), entry.entryDate);
assertEquals("Entry end time is the same as Event end time", event.getEndDate(), entry.getEndDate());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ public void testPastDueHeaderWithTasks() throws IOException, JSONException {

factory.onDataSetChanged();
factory.logWidgetEntries(method);
assertEquals("Past and Due header", DateUtil.DATETIME_MIN, factory.getWidgetEntries().get(0).getStartDate());
assertEquals("Past and Due header", DateUtil.DATETIME_MIN, factory.getWidgetEntries().get(0).entryDate);
assertEquals("Past Calendar Entry", CalendarEntry.class, factory.getWidgetEntries().get(1).getClass());
assertEquals("Due task Entry", TaskEntry.class, factory.getWidgetEntries().get(2).getClass());
assertEquals("Due task Entry", dateTime(2019, 8, 1, 9, 0),
(factory.getWidgetEntries().get(2)).getStartDate());
(factory.getWidgetEntries().get(2)).entryDate);
assertEquals("Today header", dateTime(2019, 8, 4),
(factory.getWidgetEntries().get(3)).getStartDate());
(factory.getWidgetEntries().get(3)).entryDate);
assertEquals("Future task Entry", TaskEntry.class, factory.getWidgetEntries().get(8).getClass());
assertEquals("Future task Entry", dateTime(2019, 8, 8, 21, 0),
(factory.getWidgetEntries().get(8)).getStartDate());
(factory.getWidgetEntries().get(8)).entryDate);
assertEquals("Last Entry", LastEntry.LastEntryType.LAST, ((LastEntry) factory.getWidgetEntries().get(9)).type);
assertEquals("Number of entries", 10, factory.getWidgetEntries().size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import org.andstatus.todoagenda.provider.QueryResultsStorage;
import org.andstatus.todoagenda.widget.CalendarEntry;
import org.json.JSONException;
import org.junit.Test;

import java.io.IOException;

import androidx.test.platform.app.InstrumentationRegistry;

import static org.junit.Assert.assertEquals;

/**
Expand All @@ -33,8 +33,8 @@ public void testIssue205() throws IOException, JSONException {
factory.logWidgetEntries(method);
assertEquals("Number of entries", 11, factory.getWidgetEntries().size());
assertEquals("On Saturday", "Maker Fair", ((CalendarEntry) factory.getWidgetEntries().get(4)).getEvent().getTitle());
assertEquals("On Saturday", 6, factory.getWidgetEntries().get(4).getStartDate().getDayOfWeek());
assertEquals("On Saturday", 6, factory.getWidgetEntries().get(4).entryDate.getDayOfWeek());
assertEquals("On Sunday", "Ribakovs", ((CalendarEntry) factory.getWidgetEntries().get(7)).getEvent().getTitle());
assertEquals("On Sunday", 7, factory.getWidgetEntries().get(7).getStartDate().getDayOfWeek());
assertEquals("On Sunday", 7, factory.getWidgetEntries().get(7).entryDate.getDayOfWeek());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,14 @@ private List<WidgetEntryVisualizer<? extends WidgetEntry>> getVisualizers() {

private int getTodaysPosition() {
for (int ind = 0; ind < getWidgetEntries().size() - 1; ind++) {
if (getWidgetEntries().get(ind).getStartDaySection() != TimeSection.PAST) return ind;
if (getWidgetEntries().get(ind).getTimeSection() != TimeSection.PAST) return ind;
}
return getWidgetEntries().size() - 1;
}

private int getTomorrowsPosition() {
for (int ind = 0; ind < getWidgetEntries().size() - 1; ind++) {
if (getWidgetEntries().get(ind).getStartDaySection() == TimeSection.FUTURE) return ind;
if (getWidgetEntries().get(ind).getTimeSection() == TimeSection.FUTURE) return ind;
}
return getWidgetEntries().size() > 0 ? 0 : -1;
}
Expand Down Expand Up @@ -225,17 +225,17 @@ private List<WidgetEntry> addDayHeaders(List<WidgetEntry> listIn) {
DayHeader curDayBucket = new DayHeader(DateUtil.DATETIME_MIN);
boolean pastEventsHeaderAdded = false;
for (WidgetEntry entry : listIn) {
DateTime nextStartOfDay = entry.getStartDay();
if (settings.getShowPastEventsUnderOneHeader() && nextStartOfDay.isBefore(today)) {
DateTime nextEntryDay = entry.getEntryDay();
if (settings.getShowPastEventsUnderOneHeader() && nextEntryDay.isBefore(today)) {
if(!pastEventsHeaderAdded) {
listOut.add(curDayBucket);
pastEventsHeaderAdded = true;
}
} else if (!nextStartOfDay.isEqual(curDayBucket.getStartDay())) {
} else if (!nextEntryDay.isEqual(curDayBucket.getEntryDay())) {
if (settings.getShowDaysWithoutEvents()) {
addEmptyDayHeadersBetweenTwoDays(listOut, curDayBucket.getStartDay(), nextStartOfDay);
addEmptyDayHeadersBetweenTwoDays(listOut, curDayBucket.getEntryDay(), nextEntryDay);
}
curDayBucket = new DayHeader(nextStartOfDay);
curDayBucket = new DayHeader(nextEntryDay);
listOut.add(curDayBucket);
}
listOut.add(entry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ private void createFollowingEntries(List<CalendarEntry> entryList, CalendarEntry
if (endDate.isAfter(eventProvider.getEndOfTimeRange())) {
endDate = eventProvider.getEndOfTimeRange();
}
DateTime thisDay = dayOneEntry.getStartDay().plusDays(1).withTimeAtStartOfDay();
DateTime thisDay = dayOneEntry.getEntryDay().plusDays(1).withTimeAtStartOfDay();
while (thisDay.isBefore(endDate)) {
CalendarEntry nextEntry = CalendarEntry.fromEvent(dayOneEntry.getEvent(), thisDay);
entryList.add(nextEntry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ public TextShading getShading(TextShadingPref pref) {
}

public int getEntryBackgroundColor(WidgetEntry<?> entry) {
return entry.getEndTimeSection()
return entry.getTimeSection()
.select(getPastEventsBackgroundColor(), getTodaysEventsBackgroundColor(), getEventsBackgroundColor());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ public enum TextShadingPref {
}

public static TextShadingPref forDayHeader(WidgetEntry<?> entry) {
return entry.getStartDaySection().select(DAY_HEADER_PAST, DAY_HEADER_TODAY, DAY_HEADER_FUTURE);
return entry.getTimeSection().select(DAY_HEADER_PAST, DAY_HEADER_TODAY, DAY_HEADER_FUTURE);
}

public static TextShadingPref forDetails(WidgetEntry<?> entry) {
return entry.getEndTimeSection().select(DAY_HEADER_PAST, DAY_HEADER_TODAY, DAY_HEADER_FUTURE);
return entry.getTimeSection().select(DAY_HEADER_PAST, DAY_HEADER_TODAY, DAY_HEADER_FUTURE);
}

public static TextShadingPref forTitle(WidgetEntry<?> entry) {
return entry.getEndTimeSection().select(ENTRY_PAST, ENTRY_TODAY, ENTRY_FUTURE);
return entry.getTimeSection().select(ENTRY_PAST, ENTRY_TODAY, ENTRY_FUTURE);
}

}
49 changes: 31 additions & 18 deletions app/src/main/java/org/andstatus/todoagenda/util/DateUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import android.text.format.DateUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.andstatus.todoagenda.R;
import org.andstatus.todoagenda.prefs.InstanceSettings;
import org.joda.time.DateTime;
Expand All @@ -16,14 +19,13 @@
import java.util.Formatter;
import java.util.Locale;

import androidx.annotation.NonNull;

public class DateUtil {

private static final String COMMA_SPACE = ", ";
private static volatile DateTime mNow = null;
private static volatile DateTime mNowSetAt = DateTime.now();
public static final DateTime DATETIME_MIN = new DateTime(0, DateTimeZone.UTC);
public static final DateTime DATETIME_MAX = new DateTime(Long.MAX_VALUE, DateTimeZone.UTC);

public static boolean isMidnight(DateTime date) {
return date.isEqual(date.withTimeAtStartOfDay());
Expand Down Expand Up @@ -86,37 +88,30 @@ public static CharSequence getDaysFromTodayString(Context context, int daysFromT
}
}

public static boolean isToday(DateTime date) {
return !isBeforeToday(date) && date.isBefore(DateUtil.now(date.getZone()).plusDays(1).withTimeAtStartOfDay());
public static boolean isToday(@Nullable DateTime date) {
return isDateDefined(date) && !isBeforeToday(date) && date.isBefore(DateUtil.now(date.getZone()).plusDays(1).withTimeAtStartOfDay());
}

public static boolean isBeforeToday(DateTime date) {
return date.isBefore(DateUtil.now(date.getZone()).withTimeAtStartOfDay());
public static boolean isBeforeToday(@Nullable DateTime date) {
return isDateDefined(date) && date.isBefore(DateUtil.now(date.getZone()).withTimeAtStartOfDay());
}

public static boolean isAfterToday(DateTime date) {
return !date.isBefore(DateUtil.now(date.getZone()).withTimeAtStartOfDay().plusDays(1));
public static boolean isAfterToday(@Nullable DateTime date) {
return isDateDefined(date) && !date.isBefore(DateUtil.now(date.getZone()).withTimeAtStartOfDay().plusDays(1));
}

public static boolean isBeforeNow(DateTime date) {
return date.isBefore(now(date.getZone()));
public static boolean isBeforeNow(@Nullable DateTime date) {
return isDateDefined(date) && date.isBefore(now(date.getZone()));
}

public static DateTime startOfTomorrow(DateTimeZone zone) {
return startOfNextDay(DateUtil.now(zone));
}

public static DateTime startOfNextDay(DateTime date) {
return date.plusDays(1).withTimeAtStartOfDay();
}

public static DateTime endOfToday(DateTimeZone zone) {
return endOfSameDay(DateUtil.now(zone));
}

public static DateTime endOfSameDay(DateTime date) {
return date.plusDays(1).withTimeAtStartOfDay().minusSeconds(1);
}

public static void setNow(DateTime now) {
mNowSetAt = DateTime.now();
mNow = now;
Expand Down Expand Up @@ -173,4 +168,22 @@ public static String formatLogDateTime(long time) {
}
return Long.toString(time); // Fallback if above doesn't work
}

public static boolean isSameDate(@Nullable DateTime date, @Nullable DateTime other) {
if (date == null && other == null) return true;
if (date == null || other == null) return false;

return date.equals(other);
}

public static boolean isSameDay(@Nullable DateTime date, @Nullable DateTime other) {
if (date == null && other == null) return true;
if (date == null || other == null) return false;

return date.year().equals(other.year()) && date.dayOfYear().equals(other.dayOfYear());
}

public static boolean isDateDefined(@Nullable DateTime dateTime) {
return dateTime != null && dateTime.isAfter(DATETIME_MIN) && dateTime.isBefore(DATETIME_MAX);
}
}
Loading

0 comments on commit f367a1c

Please sign in to comment.