From 4b88c1d1c07ffbb2b46943d023511f2f88fda613 Mon Sep 17 00:00:00 2001 From: Alex Styl Date: Sun, 5 Feb 2017 15:36:06 +0000 Subject: [PATCH 1/5] Dummy way of showing ads --- common/versions.gradle | 2 +- mobile/build.gradle | 4 ++++ .../specialdates/upcoming/AdViewModel.java | 13 ++++++++++ .../UpcomingRowViewModelsBuilder.java | 3 +++ .../upcoming/UpcomingRowViewType.java | 8 +++---- .../upcoming/view/AdViewHolder.java | 24 +++++++++++++++++++ .../view/UpcomingViewHolderFactory.java | 11 +++++++++ mobile/src/main/res/values/admob.xml | 5 ++++ 8 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java create mode 100644 mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/AdViewHolder.java create mode 100644 mobile/src/main/res/values/admob.xml diff --git a/common/versions.gradle b/common/versions.gradle index 982c8505..c534ad7b 100644 --- a/common/versions.gradle +++ b/common/versions.gradle @@ -1,5 +1,5 @@ ext { - android_support_version = '25.1.0' + android_support_version = '25.1.1' play_services_version = '10.0.1' } diff --git a/mobile/build.gradle b/mobile/build.gradle index b9ef538e..adcaf557 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -33,6 +33,7 @@ android { versionCode androidVersionCode versionName androidVersionName manifestPlaceholders = [crashlyticsApiKey: crashlyticsKey] + resValue "string", "admob_unit_id", "\"$adMobUnitId\"" } buildTypes { @@ -89,6 +90,9 @@ dependencies { compile "com.google.android.gms:play-services-wearable:$play_services_version" compile 'com.theartofdev.edmodo:android-image-cropper:2.3.1' + compile "com.google.firebase:firebase-core:$play_services_version" + compile "com.google.firebase:firebase-ads:$play_services_version" + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' debugCompile 'com.facebook.stetho:stetho:1.3.0' diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java new file mode 100644 index 00000000..d1d0cd46 --- /dev/null +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java @@ -0,0 +1,13 @@ +package com.alexstyl.specialdates.upcoming; + +final public class AdViewModel implements UpcomingRowViewModel { + @Override + public int getViewType() { + return UpcomingRowViewType.AD; + } + + @Override + public long getId() { + return 1337; + } +} diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java index 509430c2..bdb22c97 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java @@ -81,6 +81,9 @@ public List build() { ); rowsViewModels.add(viewModel); previousDate = indexDate; + if (rowsViewModels.size() % 2 == 0) { + rowsViewModels.add(new AdViewModel()); + } } indexDate = indexDate.addDay(1); diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewType.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewType.java index 640adca7..dedbf01a 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewType.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewType.java @@ -5,19 +5,19 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import static com.alexstyl.specialdates.upcoming.UpcomingRowViewType.UPCOMING_EVENTS; -import static com.alexstyl.specialdates.upcoming.UpcomingRowViewType.MONTH; -import static com.alexstyl.specialdates.upcoming.UpcomingRowViewType.YEAR; +import static com.alexstyl.specialdates.upcoming.UpcomingRowViewType.*; @Retention(RetentionPolicy.SOURCE) @IntDef({ MONTH, UPCOMING_EVENTS, - YEAR + YEAR, + AD }) public @interface UpcomingRowViewType { int MONTH = 0; int UPCOMING_EVENTS = 1; int YEAR = 2; + int AD = 3; } diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/AdViewHolder.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/AdViewHolder.java new file mode 100644 index 00000000..e2dac1dd --- /dev/null +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/AdViewHolder.java @@ -0,0 +1,24 @@ +package com.alexstyl.specialdates.upcoming.view; + +import android.view.View; + +import com.alexstyl.specialdates.upcoming.AdViewModel; +import com.google.android.gms.ads.AdRequest; +import com.google.android.gms.ads.NativeExpressAdView; + +final class AdViewHolder extends UpcomingRowViewHolder { + + private final NativeExpressAdView adView; + + AdViewHolder(View convertView, NativeExpressAdView adView) { + super(convertView); + this.adView = adView; + } + + @Override + public void bind(AdViewModel element, OnUpcomingEventClickedListener listener) { + // ads handle clicking by themselves + adView.loadAd(new AdRequest.Builder() + .build()); + } +} diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingViewHolderFactory.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingViewHolderFactory.java index fce784bd..63ffd806 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingViewHolderFactory.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingViewHolderFactory.java @@ -8,9 +8,14 @@ import com.alexstyl.specialdates.R; import com.alexstyl.specialdates.images.ImageLoader; import com.alexstyl.specialdates.upcoming.UpcomingRowViewType; +import com.google.android.gms.ads.AdSize; +import com.google.android.gms.ads.NativeExpressAdView; import com.novoda.notils.caster.Views; import com.novoda.notils.exception.DeveloperError; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + final class UpcomingViewHolderFactory { private final LayoutInflater layoutInflater; @@ -35,6 +40,12 @@ public UpcomingRowViewHolder createFor(int viewType, ViewGroup parent) { View view = layoutInflater.inflate(R.layout.row_header, parent, false); TextView headerView = (TextView) view.findViewById(R.id.upcoming_event_header); return new YearViewHolder(view, headerView); + } else if (viewType == UpcomingRowViewType.AD) { + NativeExpressAdView adView = new NativeExpressAdView(parent.getContext()); + adView.setLayoutParams(new ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); + adView.setAdSize(new AdSize(AdSize.FULL_WIDTH, 132)); + adView.setAdUnitId(parent.getResources().getString(R.string.admob_unit_id)); + return new AdViewHolder(adView, adView); } else { throw new DeveloperError("Invalid viewType " + viewType); } diff --git a/mobile/src/main/res/values/admob.xml b/mobile/src/main/res/values/admob.xml new file mode 100644 index 00000000..f82d83d1 --- /dev/null +++ b/mobile/src/main/res/values/admob.xml @@ -0,0 +1,5 @@ + + + 360x132 + From ecb097dae21c23d84c24f45c2777112b6cf7c1f9 Mon Sep 17 00:00:00 2001 From: Alex Styl Date: Wed, 8 Feb 2017 22:22:26 +0000 Subject: [PATCH 2/5] Add rules around ads --- .../com/alexstyl/specialdates/date/Date.java | 1 + .../specialdates/upcoming/AdViewModel.java | 28 ++++++++ .../upcoming/UpcomingEventsAdRules.java | 11 +++ .../UpcomingEventsFreeUserAdRules.java | 30 ++++++++ .../upcoming/UpcomingEventsLoader.java | 6 +- .../UpcomingRowViewModelsBuilder.java | 23 +++++-- .../alexstyl/specialdates/TestContact.java | 5 +- .../specialdates/contact/ContactTest.java | 3 +- .../upcoming/UpcomingEventsNoAdRules.java | 23 +++++++ .../UpcomingRowViewModelsBuilderTest.java | 68 +++++++++++-------- 10 files changed, 157 insertions(+), 41 deletions(-) create mode 100644 mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsAdRules.java create mode 100644 mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFreeUserAdRules.java create mode 100644 mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingEventsNoAdRules.java diff --git a/mobile/src/main/java/com/alexstyl/specialdates/date/Date.java b/mobile/src/main/java/com/alexstyl/specialdates/date/Date.java index 56131556..e3bba3f6 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/date/Date.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/date/Date.java @@ -16,6 +16,7 @@ */ public class Date implements ShortDate { + public static final Date BEGINNING_OF_TIME = Date.on(1, JANUARY, NO_YEAR); private final LocalDate localDate; private final Optional year; diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java index d1d0cd46..ef69a177 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/AdViewModel.java @@ -1,6 +1,14 @@ package com.alexstyl.specialdates.upcoming; +import com.alexstyl.specialdates.date.Date; + final public class AdViewModel implements UpcomingRowViewModel { + private final Date afterDate; + + AdViewModel(Date afterDate) { + this.afterDate = afterDate; + } + @Override public int getViewType() { return UpcomingRowViewType.AD; @@ -10,4 +18,24 @@ public int getViewType() { public long getId() { return 1337; } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + AdViewModel that = (AdViewModel) o; + + return afterDate.equals(that.afterDate); + + } + + @Override + public int hashCode() { + return afterDate.hashCode(); + } } diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsAdRules.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsAdRules.java new file mode 100644 index 00000000..ce106f39 --- /dev/null +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsAdRules.java @@ -0,0 +1,11 @@ +package com.alexstyl.specialdates.upcoming; + +interface UpcomingEventsAdRules { + boolean shouldAppendAdForEndOfMonth(int index); + + void onNewMonthAdded(int index); + + boolean shouldAppendAdAt(int index); + + void onNewAdAdded(int index); +} diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFreeUserAdRules.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFreeUserAdRules.java new file mode 100644 index 00000000..3a5d5e97 --- /dev/null +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFreeUserAdRules.java @@ -0,0 +1,30 @@ +package com.alexstyl.specialdates.upcoming; + +final class UpcomingEventsFreeUserAdRules implements UpcomingEventsAdRules { + + private int lastAdIndex = 0; + private boolean monthHandled = false; + private int DAY_INTERVAL = 2; + + @Override + public boolean shouldAppendAdForEndOfMonth(int index) { + return index - lastAdIndex >= DAY_INTERVAL; + } + + @Override + public void onNewMonthAdded(int index) { + monthHandled = false; + lastAdIndex = index; + } + + @Override + public boolean shouldAppendAdAt(int index) { + return !monthHandled && index - lastAdIndex >= DAY_INTERVAL; + } + + @Override + public void onNewAdAdded(int index) { + monthHandled = true; + lastAdIndex = index; + } +} diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsLoader.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsLoader.java index 0d27e4b2..09e2fddd 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsLoader.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsLoader.java @@ -88,7 +88,11 @@ private List calculateEventsBetween(TimePeriod period) { new NamedaysViewModelFactory(today), MonthLabels.forLocale(Locale.getDefault()) ); - UpcomingRowViewModelsBuilder upcomingRowViewModelsBuilder = new UpcomingRowViewModelsBuilder(period, upcomingRowViewModelFactory) + UpcomingRowViewModelsBuilder upcomingRowViewModelsBuilder = new UpcomingRowViewModelsBuilder( + period, + upcomingRowViewModelFactory, + new UpcomingEventsFreeUserAdRules() + ) .withContactEvents(contactEvents); if (shouldLoadBankHolidays()) { diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java index bdb22c97..10fd8ef8 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java @@ -17,17 +17,19 @@ final class UpcomingRowViewModelsBuilder { private static final List NO_CELEBRATIONS = Collections.emptyList(); private static final List NO_CONTACT_EVENTS = Collections.emptyList(); - private static final DateComparator COMPARATOR = DateComparator.INSTANCE; + private final DateComparator dateComparator = DateComparator.INSTANCE; private final HashMapList contactEvents = new HashMapList<>(); private final HashMap namedays = new HashMap<>(); private final HashMap bankHolidays = new HashMap<>(); private final TimePeriod duration; private final UpcomingEventRowViewModelFactory upcomingRowViewModelFactory; + private final UpcomingEventsAdRules adRules; - UpcomingRowViewModelsBuilder(TimePeriod duration, UpcomingEventRowViewModelFactory upcomingRowViewModelFactory) { + UpcomingRowViewModelsBuilder(TimePeriod duration, UpcomingEventRowViewModelFactory upcomingRowViewModelFactory, UpcomingEventsAdRules adRules) { this.duration = duration; this.upcomingRowViewModelFactory = upcomingRowViewModelFactory; + this.adRules = adRules; } UpcomingRowViewModelsBuilder withContactEvents(List contactEvents) { @@ -64,14 +66,24 @@ public List build() { Date lastDate = duration.getEndingDate(); Date previousDate = Date.startOfTheYear(indexDate.getYear()); - while (COMPARATOR.compare(indexDate, lastDate) <= 0) { + + int index = 0; + while (dateComparator.compare(indexDate, lastDate) <= 0) { AnnualDate annualDate = new AnnualDate(indexDate); if (containsAnyEventsOn(annualDate)) { if (indexDate.getYear() != previousDate.getYear()) { rowsViewModels.add(upcomingRowViewModelFactory.createRowForYear(indexDate.getYear())); } if (indexDate.getMonth() != previousDate.getMonth()) { + if (adRules.shouldAppendAdForEndOfMonth(index)) { + rowsViewModels.add(new AdViewModel(indexDate)); + } rowsViewModels.add(upcomingRowViewModelFactory.createRowForMonth(indexDate.getMonth())); + adRules.onNewMonthAdded(index); + } + if (adRules.shouldAppendAdAt(index)) { + rowsViewModels.add(new AdViewModel(indexDate)); + adRules.onNewAdAdded(index); } UpcomingRowViewModel viewModel = upcomingRowViewModelFactory.createEventViewModel( indexDate, @@ -81,11 +93,8 @@ public List build() { ); rowsViewModels.add(viewModel); previousDate = indexDate; - if (rowsViewModels.size() % 2 == 0) { - rowsViewModels.add(new AdViewModel()); - } + index++; } - indexDate = indexDate.addDay(1); } return rowsViewModels; diff --git a/mobile/src/test/java/com/alexstyl/specialdates/TestContact.java b/mobile/src/test/java/com/alexstyl/specialdates/TestContact.java index 6fd29be8..e280cef1 100644 --- a/mobile/src/test/java/com/alexstyl/specialdates/TestContact.java +++ b/mobile/src/test/java/com/alexstyl/specialdates/TestContact.java @@ -2,7 +2,6 @@ import android.content.Context; import android.net.Uri; -import android.view.View; import com.alexstyl.specialdates.contact.Contact; import com.alexstyl.specialdates.contact.actions.LabeledAction; @@ -26,7 +25,7 @@ public Uri getLookupUri() { } @Override - public void displayQuickInfo(Context context, View view) { + public void displayQuickInfo(Context context) { throw new UnsupportedOperationException("Not supported"); } @@ -35,6 +34,4 @@ public Uri getImagePath() { throw new UnsupportedOperationException("Not supported"); } - - } diff --git a/mobile/src/test/java/com/alexstyl/specialdates/contact/ContactTest.java b/mobile/src/test/java/com/alexstyl/specialdates/contact/ContactTest.java index c11a929f..02c1daa9 100644 --- a/mobile/src/test/java/com/alexstyl/specialdates/contact/ContactTest.java +++ b/mobile/src/test/java/com/alexstyl/specialdates/contact/ContactTest.java @@ -2,7 +2,6 @@ import android.content.Context; import android.net.Uri; -import android.view.View; import com.alexstyl.specialdates.DisplayName; import com.alexstyl.specialdates.contact.actions.LabeledAction; @@ -46,7 +45,7 @@ public Uri getLookupUri() { } @Override - public void displayQuickInfo(Context context, View view) { + public void displayQuickInfo(Context context) { throw new UnsupportedOperationException(); } diff --git a/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingEventsNoAdRules.java b/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingEventsNoAdRules.java new file mode 100644 index 00000000..263d4c3a --- /dev/null +++ b/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingEventsNoAdRules.java @@ -0,0 +1,23 @@ +package com.alexstyl.specialdates.upcoming; + +final class UpcomingEventsNoAdRules implements UpcomingEventsAdRules { + @Override + public boolean shouldAppendAdForEndOfMonth(int index) { + return false; + } + + @Override + public void onNewMonthAdded(int index) { + // do nothing + } + + @Override + public boolean shouldAppendAdAt(int index) { + return false; + } + + @Override + public void onNewAdAdded(int index) { + throw new IllegalStateException(UpcomingEventsNoAdRules.class.getName() + " does not allow ads to be added"); + } +} diff --git a/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilderTest.java b/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilderTest.java index c9f1f195..099b5ad9 100644 --- a/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilderTest.java +++ b/mobile/src/test/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilderTest.java @@ -1,5 +1,7 @@ package com.alexstyl.specialdates.upcoming; +import android.support.annotation.NonNull; + import com.alexstyl.resources.ColorResources; import com.alexstyl.resources.StringResources; import com.alexstyl.specialdates.DisplayName; @@ -13,8 +15,8 @@ import com.alexstyl.specialdates.events.peopleevents.StandardEventType; import com.alexstyl.specialdates.search.DumbTestResources; -import java.util.Arrays; import java.util.List; +import java.util.Locale; import org.junit.Before; import org.junit.Test; @@ -23,6 +25,8 @@ import org.mockito.runners.MockitoJUnitRunner; import static com.alexstyl.specialdates.date.DateConstants.*; +import static com.alexstyl.specialdates.date.TimePeriod.between; +import static java.util.Arrays.asList; import static java.util.Collections.singletonList; import static org.fest.assertions.api.Assertions.assertThat; @@ -40,6 +44,7 @@ public class UpcomingRowViewModelsBuilderTest { private ColorResources mockColorResources; @Mock private StringResources mockStringResources; + private UpcomingEventsAdRules adRules = new UpcomingEventsNoAdRules(); @Before public void setUp() { @@ -51,7 +56,7 @@ public void setUp() { mockStringResources, new BankHolidayViewModelFactory(), new NamedaysViewModelFactory(today), - monthLabels + MonthLabels.forLocale(Locale.getDefault()) ); } @@ -59,9 +64,9 @@ public void setUp() { @Test public void celebrationDateIsCreatedCorrectlyForDifferentYear() { ContactEvent event = aContactEventOn(Date.on(1, JANUARY, 1990)); - TimePeriod duration = TimePeriod.between(Date.on(1, JANUARY, 2016), Date.on(1, DECEMBER, 2016)); + TimePeriod duration = between(Date.on(1, JANUARY, 2016), Date.on(1, DECEMBER, 2016)); - List dates = new UpcomingRowViewModelsBuilder(duration, upcomingEventRowViewModelFactory) + List dates = builder(duration) .withContactEvents(singletonList(event)) .build(); @@ -75,7 +80,7 @@ public void givenASingleContactEvent_thenOneCelebrationDateIsCreated() { TimePeriod duration = timeOf(event); - List dates = new UpcomingRowViewModelsBuilder(duration, upcomingEventRowViewModelFactory) + List dates = builder(duration) .withContactEvents(contactEvents) .build(); @@ -84,37 +89,39 @@ public void givenASingleContactEvent_thenOneCelebrationDateIsCreated() { @Test public void givenTwoContactEventsOnSameDate_thenOneCelebrationDateIsCreated() { - List contactEventsList = Arrays.asList( - aContactEventOn(FEBRUARY_1st), - aContactEventOn(FEBRUARY_1st) - ); - List dates = new UpcomingRowViewModelsBuilder(TimePeriod.between(FEBRUARY_1st, FEBRUARY_1st), upcomingEventRowViewModelFactory) - .withContactEvents(contactEventsList) + List dates = builder(between(FEBRUARY_1st, FEBRUARY_1st)) + .withContactEvents(asList( + aContactEventOn(FEBRUARY_1st), + aContactEventOn(FEBRUARY_1st) + )) .build(); - assertThat(dates.size()).isEqualTo(1); + int datesCount = 1; + int monthCount = 1; + assertThat(dates.size()).isEqualTo(datesCount + monthCount); } @Test public void givenTwoContactEventsOnDifferentDate_thenTwoCelebrationDateAreCreated() { - List contactEventsList = Arrays.asList( - aContactEventOn(FEBRUARY_1st), - aContactEventOn(FEBRUARY_3rd) - ); - List dates = new UpcomingRowViewModelsBuilder(TimePeriod.between(FEBRUARY_1st, FEBRUARY_3rd), upcomingEventRowViewModelFactory) - .withContactEvents(contactEventsList) + List dates = builder(between(FEBRUARY_1st, FEBRUARY_3rd)) + .withContactEvents(asList( + aContactEventOn(FEBRUARY_1st), + aContactEventOn(FEBRUARY_3rd) + )) .build(); - assertThat(dates.size()).isEqualTo(2); + int monthCount = 1; + int datesCount = 2; + assertThat(dates.size()).isEqualTo(datesCount + monthCount); } @Test public void givenABankHoliday_thenACelebrationDateIsCreated() { BankHoliday bankHoliday = aBankHoliday(); List bankHolidays = singletonList(bankHoliday); - List dates = new UpcomingRowViewModelsBuilder(TimePeriod.between(bankHoliday.getDate(), bankHoliday.getDate()), upcomingEventRowViewModelFactory) + List dates = builder(between(bankHoliday.getDate(), bankHoliday.getDate())) .withBankHolidays(bankHolidays) .build(); @@ -122,14 +129,21 @@ public void givenABankHoliday_thenACelebrationDateIsCreated() { } @Test - public void givenEventsOnDifferentEvents_thenACelebrationDatesForEachOneAreCreated() { - List dates = new UpcomingRowViewModelsBuilder(TimePeriod.between(FEBRUARY_1st, MARCH_5th), upcomingEventRowViewModelFactory) - .withContactEvents(singletonList(aContactEventOn(FEBRUARY_1st))) - .withBankHolidays(singletonList(aBankHolidayOn(FEBRUARY_3rd))) - .withNamedays(singletonList(new NamesInADate(MARCH_5th, singletonList("Name")))) + public void givenEventsOnDifferentMonths_thenACelebrationDatesForEachOneAreCreated() { + List dates = builder(between(FEBRUARY_1st, MARCH_5th)) + .withContactEvents(asList(aContactEventOn(FEBRUARY_1st))) + .withBankHolidays(asList(aBankHolidayOn(FEBRUARY_3rd))) + .withNamedays(asList(new NamesInADate(MARCH_5th, singletonList("Name")))) .build(); - assertThat(dates.size()).isEqualTo(3); + int datesCount = 3; + int monthsCounts = 2; + assertThat(dates.size()).isEqualTo(datesCount + monthsCounts); + } + + @NonNull + private UpcomingRowViewModelsBuilder builder(TimePeriod timePeriod) { + return new UpcomingRowViewModelsBuilder(timePeriod, upcomingEventRowViewModelFactory, adRules); } private static BankHoliday aBankHolidayOn(Date date) { @@ -150,7 +164,7 @@ private static ContactEvent aContactEventOn(Date date) { } private static TimePeriod timeOf(ContactEvent event) { - return TimePeriod.between(event.getDate(), event.getDate()); + return between(event.getDate(), event.getDate()); } } From 4edb304853120f4181757cf59ba5f334aa200910 Mon Sep 17 00:00:00 2001 From: Alex Styl Date: Wed, 8 Feb 2017 22:28:33 +0000 Subject: [PATCH 3/5] Use same paddings between all cards --- .../specialdates/upcoming/view/UpcomingEventsListView.java | 3 +++ mobile/src/main/res/layout/row_header.xml | 2 +- mobile/src/main/res/layout/row_upcoming_day.xml | 2 -- mobile/src/main/res/values/upcoming-resources.xml | 3 +-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingEventsListView.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingEventsListView.java index 75bee5b4..373fd1fb 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingEventsListView.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/view/UpcomingEventsListView.java @@ -8,9 +8,11 @@ import android.util.AttributeSet; import android.view.LayoutInflater; +import com.alexstyl.specialdates.R; import com.alexstyl.specialdates.images.ImageLoader; import com.alexstyl.specialdates.images.PauseImageLoadingScrollListener; import com.alexstyl.specialdates.ui.widget.ScrollingLinearLayoutManager; +import com.alexstyl.specialdates.ui.widget.SpacesItemDecoration; import com.alexstyl.specialdates.upcoming.UpcomingRowViewModel; import java.util.List; @@ -35,6 +37,7 @@ public UpcomingEventsListView(Context context, @Nullable AttributeSet attrs) { setAdapter(adapter); addOnScrollListener(PauseImageLoadingScrollListener.newInstance(imageLoader)); + addItemDecoration(new SpacesItemDecoration(getResources().getDimensionPixelSize(R.dimen.upcoming_vertical_padding_between_cards), 1)); } public void updateWith(List dates, OnUpcomingEventClickedListener listener) { diff --git a/mobile/src/main/res/layout/row_header.xml b/mobile/src/main/res/layout/row_header.xml index a92f3e9b..0b725efc 100644 --- a/mobile/src/main/res/layout/row_header.xml +++ b/mobile/src/main/res/layout/row_header.xml @@ -5,7 +5,7 @@ style="@style/Upcoming.MonthHeader" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/upcoming_vertical_bottom_padding_between_each_card" + android:layout_marginBottom="@dimen/upcoming_vertical_padding_between_cards" android:layout_marginLeft="@dimen/upcoming_event_padding_horizontal" android:layout_marginRight="@dimen/upcoming_event_padding_horizontal" android:layout_marginTop="@dimen/padding_month_header_vertical" diff --git a/mobile/src/main/res/layout/row_upcoming_day.xml b/mobile/src/main/res/layout/row_upcoming_day.xml index d8d14d11..15a7f010 100644 --- a/mobile/src/main/res/layout/row_upcoming_day.xml +++ b/mobile/src/main/res/layout/row_upcoming_day.xml @@ -5,8 +5,6 @@ style="@style/CardViewStyle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/upcoming_vertical_bottom_padding_between_each_card" - android:layout_marginTop="@dimen/upcoming_vertical_top_padding_between_each_card" android:orientation="vertical" tools:showIn="@layout/activity_main"> diff --git a/mobile/src/main/res/values/upcoming-resources.xml b/mobile/src/main/res/values/upcoming-resources.xml index 3e46d6ec..e579602b 100644 --- a/mobile/src/main/res/values/upcoming-resources.xml +++ b/mobile/src/main/res/values/upcoming-resources.xml @@ -4,8 +4,7 @@ @string/namedays +%d more - 8dp - @dimen/upcoming_vertical_top_padding_between_each_card + 12dp 8dp 16dp From 801e1d9bb4855917a10fcfdb9d9435797f026c95 Mon Sep 17 00:00:00 2001 From: Alex Styl Date: Wed, 8 Feb 2017 22:50:47 +0000 Subject: [PATCH 4/5] Add ad before year change --- .../upcoming/UpcomingRowViewModelsBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java index 10fd8ef8..c2c06805 100644 --- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java +++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingRowViewModelsBuilder.java @@ -71,16 +71,17 @@ public List build() { while (dateComparator.compare(indexDate, lastDate) <= 0) { AnnualDate annualDate = new AnnualDate(indexDate); if (containsAnyEventsOn(annualDate)) { - if (indexDate.getYear() != previousDate.getYear()) { - rowsViewModels.add(upcomingRowViewModelFactory.createRowForYear(indexDate.getYear())); - } if (indexDate.getMonth() != previousDate.getMonth()) { if (adRules.shouldAppendAdForEndOfMonth(index)) { rowsViewModels.add(new AdViewModel(indexDate)); } + if (indexDate.getYear() != previousDate.getYear()) { + rowsViewModels.add(upcomingRowViewModelFactory.createRowForYear(indexDate.getYear())); + } rowsViewModels.add(upcomingRowViewModelFactory.createRowForMonth(indexDate.getMonth())); adRules.onNewMonthAdded(index); } + if (adRules.shouldAppendAdAt(index)) { rowsViewModels.add(new AdViewModel(indexDate)); adRules.onNewAdAdded(index); From 5d15751e948cc6b799849ba6581792538f0429ce Mon Sep 17 00:00:00 2001 From: Alex Styl Date: Thu, 9 Feb 2017 23:07:29 +0000 Subject: [PATCH 5/5] Add admob in secret sample --- secret.gradle.sample | 1 + 1 file changed, 1 insertion(+) diff --git a/secret.gradle.sample b/secret.gradle.sample index 8c440c46..35d3ff01 100644 --- a/secret.gradle.sample +++ b/secret.gradle.sample @@ -3,4 +3,5 @@ ext { crashlyticsKey = "1234567890123456789012345678901234567890" androidVendingKey = "Include your vending key here" mixpanelKey = "Include your mix panel key here" + adMobUnitId = "Your own admob unit id here" }