diff --git a/.travis.yml b/.travis.yml
index e46959f8..ae8d40dd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,5 @@
language: android
-jdk: oraclejdk7
+jdk: oraclejdk8
sudo: false
cache:
directories:
diff --git a/mobile/build.gradle b/mobile/build.gradle
index 74abfabe..e1c6175f 100644
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -12,8 +12,8 @@ apply plugin: 'io.fabric'
apply plugin: 'com.google.gms.google-services'
android {
- compileSdkVersion 23
- buildToolsVersion '23.0.2'
+ compileSdkVersion 24
+ buildToolsVersion '24.0.2'
applicationVariants.all { variant ->
@@ -28,7 +28,7 @@ android {
defaultConfig {
applicationId 'com.alexstyl.specialdates'
minSdkVersion 16
- targetSdkVersion 22
+ targetSdkVersion 24
versionCode 57
versionName '3.8'
@@ -67,12 +67,14 @@ repositories {
dependencies {
+
compile fileTree(dir: 'libs', exclude: 'android-support-v4.jar', include: ['*.jar'])
compile project(':numberpicker')
- compile 'com.android.support:support-annotations:23.3.0'
- compile 'com.android.support:design:23.3.0'
- compile 'com.android.support:appcompat-v7:23.3.0'
- compile 'com.android.support:recyclerview-v7:23.3.0'
+ compile 'com.android.support:support-annotations:24.2.0'
+ compile 'com.android.support:design:24.2.0'
+ compile 'com.android.support:appcompat-v7:24.2.0'
+ compile 'com.android.support:recyclerview-v7:24.2.0'
+ compile 'com.android.support:transition:24.2.0'
compile 'net.danlew:android.joda:2.8.0'
compile('de.psdev.licensesdialog:licensesdialog:1.5.0') {
exclude module: 'support-v4'
diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml
index 86974324..ab5fdb06 100644
--- a/mobile/src/main/AndroidManifest.xml
+++ b/mobile/src/main/AndroidManifest.xml
@@ -26,6 +26,7 @@
@@ -67,6 +68,7 @@
Created by alexstyl on 05/02/15.
- */
-public class PayPal {
-
- public static final String URL_DONATIONS = "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=M7V8YHDL2NVUC";
-}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/about/AboutActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/about/AboutActivity.java
index 2d79bdd4..1f0bb2af 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/about/AboutActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/about/AboutActivity.java
@@ -11,6 +11,7 @@
import com.alexstyl.specialdates.Navigator;
import com.alexstyl.specialdates.R;
+import com.alexstyl.specialdates.analytics.Firebase;
import com.alexstyl.specialdates.theming.AttributeExtractor;
import com.alexstyl.specialdates.ui.CheatsSheat;
import com.alexstyl.specialdates.ui.activity.MainActivity;
@@ -41,7 +42,7 @@ protected void onCreate(Bundle savedInstanceState) {
SimpleChromeCustomTabs.initialize(this);
- navigator = new Navigator(this);
+ navigator = new Navigator(this, Firebase.get(this));
MementoToolbar toolbar = Views.findById(this, R.id.memento_toolbar);
setSupportActionBar(toolbar);
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/addevent/AddBirthdayActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/addevent/AddBirthdayActivity.java
index cc5df3b4..907ccb6c 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/addevent/AddBirthdayActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/addevent/AddBirthdayActivity.java
@@ -9,10 +9,9 @@
import com.alexstyl.specialdates.addevent.ui.ContactHeroView;
import com.alexstyl.specialdates.addevent.ui.ContactsAutoCompleteView;
import com.alexstyl.specialdates.analytics.Action;
-import com.alexstyl.specialdates.analytics.Analytics;
import com.alexstyl.specialdates.analytics.ActionWithParameters;
+import com.alexstyl.specialdates.analytics.Analytics;
import com.alexstyl.specialdates.analytics.Firebase;
-import com.alexstyl.specialdates.analytics.Screen;
import com.alexstyl.specialdates.contact.Birthday;
import com.alexstyl.specialdates.contact.Contact;
import com.alexstyl.specialdates.theming.MementoTheme;
@@ -36,8 +35,7 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
analytics = Firebase.get(this);
- analytics.trackScreen(Screen.ADD_BIRTHDAY);
- MementoTheme theme = Themer.get().getCurrentTheme();
+ MementoTheme theme = Themer.get(this).getCurrentTheme();
setContentView(R.layout.activity_add_birthday, theme);
contactHeroView = Views.findById(this, R.id.addbirthday_hero);
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/addevent/BirthdayQuery.java b/mobile/src/main/java/com/alexstyl/specialdates/addevent/BirthdayQuery.java
index dabfff15..4ec4f5a0 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/addevent/BirthdayQuery.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/addevent/BirthdayQuery.java
@@ -15,7 +15,6 @@
import com.alexstyl.specialdates.date.DateParseException;
import com.alexstyl.specialdates.date.DayDate;
import com.alexstyl.specialdates.util.DateParser;
-import com.alexstyl.specialdates.util.Utils;
import com.novoda.notils.exception.DeveloperError;
public class BirthdayQuery {
@@ -127,8 +126,7 @@ public static Cursor query(ContentResolver cr) {
}
private static final Uri CONTENT_URI = ContactsContract.Data.CONTENT_URI;
- private static final String COL_DISPLAY_NAME = Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
- : ContactsContract.Contacts.DISPLAY_NAME;
+ private static final String COL_DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
public static final String WHERE =
"(" + ContactsContract.Data.MIMETYPE + " = ? AND " +
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/contact/ContactsQuery.java b/mobile/src/main/java/com/alexstyl/specialdates/contact/ContactsQuery.java
index fcee9c80..74136715 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/contact/ContactsQuery.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/contact/ContactsQuery.java
@@ -7,20 +7,16 @@
import android.os.Build;
import android.provider.ContactsContract;
-import com.alexstyl.specialdates.util.Utils;
-
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
class ContactsQuery {
public final static Uri CONTENT_URI = ContactsContract.Data.CONTENT_URI;
- public static String COL_DISPLAY_NAME = Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY //3
- : ContactsContract.Contacts.DISPLAY_NAME;
+ public static String COL_DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
public static String COL_LOOKUP = ContactsContract.Contacts.LOOKUP_KEY;
@SuppressLint("InlinedApi")
- public final static String SORT_ORDER = Utils.hasHoneycomb() ?
- ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME;
+ public final static String SORT_ORDER = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
@SuppressLint("InlinedApi")
public static final String[] PROJECTION = {
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/datedetails/DateDetailsFragment.java b/mobile/src/main/java/com/alexstyl/specialdates/datedetails/DateDetailsFragment.java
index f2ebabf1..16806fb0 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/datedetails/DateDetailsFragment.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/datedetails/DateDetailsFragment.java
@@ -155,7 +155,7 @@ public void onActivityCreated(Bundle savedInstanceState) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- navigator = new Navigator(getActivity());
+ navigator = new Navigator(getActivity(), analytics);
analytics = Firebase.get(getActivity());
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/events/BirthdayDatabaseRefresher.java b/mobile/src/main/java/com/alexstyl/specialdates/events/BirthdayDatabaseRefresher.java
index 1d1f0ceb..54ca8dea 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/events/BirthdayDatabaseRefresher.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/events/BirthdayDatabaseRefresher.java
@@ -19,7 +19,6 @@
import com.alexstyl.specialdates.date.DayDate;
import com.alexstyl.specialdates.events.database.EventSQLiteOpenHelper;
import com.alexstyl.specialdates.util.DateParser;
-import com.alexstyl.specialdates.util.Utils;
import java.util.ArrayList;
import java.util.Collections;
@@ -120,8 +119,7 @@ public static Cursor query(ContentResolver cr) {
}
private static final Uri CONTENT_URI = ContactsContract.Data.CONTENT_URI;
- private static final String COL_DISPLAY_NAME = Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
- : ContactsContract.Contacts.DISPLAY_NAME;
+ private static final String COL_DISPLAY_NAME = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
public static final String WHERE =
"(" + ContactsContract.Data.MIMETYPE + " = ? AND " +
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/events/namedays/NamedayDatabaseRefresher.java b/mobile/src/main/java/com/alexstyl/specialdates/events/namedays/NamedayDatabaseRefresher.java
index 1936da13..c47679b0 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/events/namedays/NamedayDatabaseRefresher.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/events/namedays/NamedayDatabaseRefresher.java
@@ -22,7 +22,6 @@
import com.alexstyl.specialdates.events.database.EventSQLiteOpenHelper;
import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendar;
import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendarProvider;
-import com.alexstyl.specialdates.util.Utils;
import java.util.ArrayList;
import java.util.Collections;
@@ -230,14 +229,12 @@ private static class DeviceContactsQuery {
};
@SuppressLint("InlinedApi")
- public final static String SORT_ORDER =
- Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
- : ContactsContract.Contacts.DISPLAY_NAME;
+ public final static String SORT_ORDER = ContactsContract.Contacts.DISPLAY_NAME_PRIMARY;
@SuppressLint("InlinedApi")
public static final String[] PROJECTION = {
ContactsContract.Data.CONTACT_ID,
- Utils.hasHoneycomb() ? ContactsContract.Contacts.DISPLAY_NAME_PRIMARY : ContactsContract.Contacts.DISPLAY_NAME,
+ ContactsContract.Contacts.DISPLAY_NAME_PRIMARY
};
public static final int ID = 0;
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/images/ImageDownloader.java b/mobile/src/main/java/com/alexstyl/specialdates/images/ImageDownloader.java
index 3b60d3d5..176c9ea7 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/images/ImageDownloader.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/images/ImageDownloader.java
@@ -7,7 +7,6 @@
import android.os.Build;
import android.provider.ContactsContract;
-import com.alexstyl.specialdates.util.Utils;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
import java.io.FileNotFoundException;
@@ -33,11 +32,7 @@ protected InputStream getStreamFromContent(String imageUri, Object extra) throws
Uri uri = Uri.parse(imageUri);
if (imageUri.startsWith("content://com.android.contacts/")) {
- if (Utils.hasICS()) {
- return ContactsContract.Contacts.openContactPhotoInputStream(res, uri, true);
- } else {
- return ContactsContract.Contacts.openContactPhotoInputStream(res, uri);
- }
+ return ContactsContract.Contacts.openContactPhotoInputStream(res, uri, true);
}
return res.openInputStream(uri);
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/BackKeyEditText.java b/mobile/src/main/java/com/alexstyl/specialdates/search/BackKeyEditText.java
new file mode 100644
index 00000000..968b80a9
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/BackKeyEditText.java
@@ -0,0 +1,26 @@
+package com.alexstyl.specialdates.search;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.widget.EditText;
+
+public class BackKeyEditText extends EditText {
+ public BackKeyEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ private OnBackKeyPressedListener listener;
+
+ public void setOnBackKeyPressedListener(OnBackKeyPressedListener listener) {
+ this.listener = listener;
+ }
+
+ @Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_BACK && listener.onBackButtonPressed()) {
+ return true;
+ }
+ return super.onKeyPreIme(keyCode, event);
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/DelayedTextWatcher.java b/mobile/src/main/java/com/alexstyl/specialdates/search/DelayedTextWatcher.java
index e6545ae4..1abbeb0f 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/search/DelayedTextWatcher.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/DelayedTextWatcher.java
@@ -2,7 +2,6 @@
import android.os.Handler;
import android.text.Editable;
-import android.text.TextUtils;
import android.text.TextWatcher;
public class DelayedTextWatcher implements TextWatcher {
@@ -23,13 +22,13 @@ public DelayedTextWatcher(TextUpdatedCallback textWatchTextUpdatedCallback, Hand
this.handler = handler;
}
- private Runnable timeEndRunnable = new Runnable() {
+ private final Runnable timeEndRunnable = new Runnable() {
@Override
public void run() {
- if (TextUtils.isEmpty(text)) {
- textWatchTextUpdatedCallback.onEmptyTextEntered();
- } else {
+ if (text.length() > 0) {
textWatchTextUpdatedCallback.onTextConfirmed(text);
+ } else {
+ textWatchTextUpdatedCallback.onEmptyTextConfirmed();
}
}
};
@@ -55,7 +54,7 @@ public void afterTextChanged(Editable s) {
public interface TextUpdatedCallback {
void onTextChanged(String text);
- void onEmptyTextEntered();
+ void onEmptyTextConfirmed();
void onTextConfirmed(String text);
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/DeviceSearchFragment.java b/mobile/src/main/java/com/alexstyl/specialdates/search/DeviceSearchFragment.java
deleted file mode 100644
index ecbd54df..00000000
--- a/mobile/src/main/java/com/alexstyl/specialdates/search/DeviceSearchFragment.java
+++ /dev/null
@@ -1,319 +0,0 @@
-package com.alexstyl.specialdates.search;
-
-import android.content.Context;
-import android.os.Bundle;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.Loader;
-import android.support.v7.widget.GridLayoutManager;
-import android.support.v7.widget.LinearLayoutManager;
-import android.support.v7.widget.RecyclerView;
-import android.text.InputType;
-import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.TextView;
-
-import com.alexstyl.specialdates.R;
-import com.alexstyl.specialdates.contact.Contact;
-import com.alexstyl.specialdates.datedetails.DateDetailsActivity;
-import com.alexstyl.specialdates.date.DayDate;
-import com.alexstyl.specialdates.events.namedays.NamedayPreferences;
-import com.alexstyl.specialdates.events.namedays.NameCelebrations;
-import com.alexstyl.specialdates.ui.base.MementoFragment;
-import com.alexstyl.specialdates.ui.widget.SpacesItemDecoration;
-
-/**
- * A fragment in which the user can search for namedays and their contact's birthdays.
- *
The fragment has a different logic for when the user has enabled namedays for any language.
- * If the user has enabled to display Namedays, the search EditText will give no suggestions. Instead a custom
- * suggestion bar on top of the keyboard is going to be given to the user with names.
- * Created by alexstyl on 20/04/15.
- */
-public class DeviceSearchFragment extends MementoFragment implements NameSuggestionsAdapter.OnNameSelectedListener {
-
- private static final String KEY_QUERY = "alexstyl:key_query";
-
- private static final int ID_CONTACTS = 31;
- private static final int ID_NAMEDAYS = 32;
-
- private static final int INITAL_COUNT = 5;
-
- private int searchCounter = INITAL_COUNT;
-
- private EditText searchField;
-
- private ImageButton clearButton;
- private RecyclerView resultView;
-
- private RecyclerView namesSuggestionsView;
- private SearchResultAdapter adapter;
-
- private NameSuggestionsAdapter namesAdapter;
-
- private boolean displayNamedays;
-
- private String searchQuery;
-
- @Override
- public void onStart() {
- super.onStart();
- searchField.requestFocus();
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- outState.putString(KEY_QUERY, searchQuery);
- }
-
- private LoaderManager.LoaderCallbacks contactSearchCallbacks
- = new LoaderManager.LoaderCallbacks() {
-
- @Override
- public Loader onCreateLoader(int id, Bundle args) {
- adapter.notifyIsLoadingMore();
- return new SearchLoader(getActivity(), searchQuery, searchCounter);
- }
-
- @Override
- public void onLoadFinished(Loader loader, SearchResults searchResults) {
- if (loader.getId() == ID_CONTACTS) {
- adapter.updateSearchResults(searchResults);
- }
- }
-
- @Override
- public void onLoaderReset(Loader loader) {
- if (loader.getId() == ID_CONTACTS) {
- adapter.notifyIsLoadingMore();
- }
- }
- };
-
- private LoaderManager.LoaderCallbacks namedayLoaderCallbacks = new LoaderManager.LoaderCallbacks() {
-
- @Override
- public Loader onCreateLoader(int id, Bundle args) {
- return NamedaysLoader.newInstance(getActivity(), searchQuery);
- }
-
- @Override
- public void onLoadFinished(Loader loader, NameCelebrations results) {
- adapter.setNamedays(results);
- }
-
- @Override
- public void onLoaderReset(Loader loader) {
- adapter.setNamedays(NameCelebrations.EMPTY);
- }
- };
-
- private void startSearching() {
- getLoaderManager().restartLoader(ID_CONTACTS, null, contactSearchCallbacks);
- getLoaderManager().restartLoader(ID_NAMEDAYS, null, namedayLoaderCallbacks);
- }
-
- private void clearResults() {
- adapter.clearResults();
- if (displayNamedays) {
- namesAdapter.clearNames();
- }
- }
-
- private void hideClearButton() {
- clearButton.setVisibility(View.GONE);
- }
-
- private void showClearButton() {
- clearButton.setVisibility(View.VISIBLE);
- }
-
- private void resetSearchCounter() {
- searchCounter = INITAL_COUNT;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- displayNamedays = shouldIncludeNamedays();
- if (savedInstanceState != null) {
- searchQuery = savedInstanceState.getString(KEY_QUERY);
- }
- }
-
- private boolean shouldIncludeNamedays() {
- NamedayPreferences namedayPreferences = NamedayPreferences.newInstance(getActivity());
- return namedayPreferences.isEnabled();
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_search, container, false);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- searchField = (EditText) view.findViewById(R.id.text_search_query);
- setupSearchField();
- ImageButton closeButton = (ImageButton) view.findViewById(R.id.btn_close);
- clearButton = (ImageButton) view.findViewById(R.id.btn_clear);
- resultView = (RecyclerView) view.findViewById(android.R.id.list);
- resultView.setHasFixedSize(false);
- namesSuggestionsView = (RecyclerView) view.findViewById(R.id.nameday_suggestions);
-
- closeButton.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().finish();
- }
- }
- );
- clearButton.setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- searchField.setText(null);
- searchField.requestFocus();
- InputMethodManager imm = (InputMethodManager) getActivity()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.showSoftInput(searchField, InputMethodManager.SHOW_IMPLICIT);
-
- }
- }
- );
-
- adapter = SearchResultAdapter.newInstance(getActivity(), displayNamedays);
- adapter.setSearchResultClickListener(listener);
-
- resultView.setHasFixedSize(true);
- RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
- int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.card_spacing_between);
- resultView.addItemDecoration(new SpacesItemDecoration(spacingInPixels, 3));
- resultView.setLayoutManager(mLayoutManager);
- resultView.setAdapter(adapter);
-
- if (displayNamedays) {
- // we are loading namedays as well
- GridLayoutManager namedayManager = new GridLayoutManager(getActivity(), 1, RecyclerView.HORIZONTAL, false);
- namesAdapter = NameSuggestionsAdapter.newInstance(getActivity());
- namesAdapter.setOnNameSelectedListener(this);
- namesSuggestionsView.setHasFixedSize(true);
- namesSuggestionsView.setLayoutManager(namedayManager);
- namesSuggestionsView.setAdapter(namesAdapter);
-
- searchField.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
-
- searchField.setOnFocusChangeListener(
- new View.OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (hasFocus) {
- namesSuggestionsView.setVisibility(View.VISIBLE);
- } else {
- namesSuggestionsView.setVisibility(View.GONE);
- }
- }
- }
- );
- } else {
- namesSuggestionsView.setVisibility(View.GONE);
- }
- }
-
- private final DelayedTextWatcher.TextUpdatedCallback textUpdatedTextUpdatedCallback = new DelayedTextWatcher.TextUpdatedCallback() {
- @Override
- public void onTextChanged(String text) {
- searchQuery = text;
- updateNameSuggestions(text);
- resetSearchCounter();
- }
-
- @Override
- public void onEmptyTextEntered() {
- clearResults();
- hideClearButton();
- }
-
- @Override
- public void onTextConfirmed(String text) {
- startSearching();
- showClearButton();
- }
- };
-
- private void updateNameSuggestions(String text) {
- if (displayNamedays) {
- namesAdapter.getFilter().filter(text);
- }
- }
-
- private void setupSearchField() {
- searchField.addTextChangedListener(DelayedTextWatcher.newInstance(textUpdatedTextUpdatedCallback));
- searchField.setOnEditorActionListener(
- new TextView.OnEditorActionListener() {
- @Override
- public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- InputMethodManager imm = (InputMethodManager) getActivity()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(searchField.getWindowToken(), 0);
- resultView.requestFocus();
- return true;
- }
- return false;
- }
- }
- );
- }
-
- @Override
- public void onNameSelected(View view, final String name) {
- onNameSet(name);
- }
-
- private void onNameSet(String name) {
- // setting the text to the EditText will trigger the search for the name
- searchField.setText(name);
- namesAdapter.clearNames();
-
- InputMethodManager imm = (InputMethodManager) getActivity()
- .getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(searchField.getWindowToken(), 0);
- searchField.clearFocus();
-
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (TextUtils.isEmpty(searchQuery)) {
- hideClearButton();
- } else {
- showClearButton();
- }
- }
-
- private SearchResultAdapter.SearchResultClickListener listener = new SearchResultAdapter.SearchResultClickListener() {
-
- @Override
- public void onContactClicked(View v, Contact contact) {
- contact.displayQuickInfo(getActivity(), v);
- }
-
- @Override
- public void onNamedayClicked(View v, int month, int day) {
- DayDate dayDate = DayDate.today();
- DateDetailsActivity.startActivity(getActivity(), month, day, dayDate.getYear());
- }
-
- };
-
-}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/OnBackKeyPressedListener.java b/mobile/src/main/java/com/alexstyl/specialdates/search/OnBackKeyPressedListener.java
new file mode 100644
index 00000000..8bf8b18c
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/OnBackKeyPressedListener.java
@@ -0,0 +1,8 @@
+package com.alexstyl.specialdates.search;
+
+public interface OnBackKeyPressedListener {
+ /**
+ * @return Return true if the event has been handled
+ */
+ boolean onBackButtonPressed();
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchActivity.java
index cdea9c5a..238feabe 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchActivity.java
@@ -1,16 +1,349 @@
package com.alexstyl.specialdates.search;
import android.os.Bundle;
+import android.support.transition.Fade;
+import android.support.transition.Transition;
+import android.support.transition.TransitionManager;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.Loader;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.text.InputType;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import com.alexstyl.specialdates.R;
-import com.alexstyl.specialdates.ui.base.ThemedActivity;
+import com.alexstyl.specialdates.analytics.Firebase;
+import com.alexstyl.specialdates.analytics.Screen;
+import com.alexstyl.specialdates.contact.Contact;
+import com.alexstyl.specialdates.date.DayDate;
+import com.alexstyl.specialdates.datedetails.DateDetailsActivity;
+import com.alexstyl.specialdates.events.namedays.NameCelebrations;
+import com.alexstyl.specialdates.events.namedays.NamedayLocale;
+import com.alexstyl.specialdates.events.namedays.NamedayPreferences;
+import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendar;
+import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendarProvider;
+import com.alexstyl.specialdates.images.ImageLoader;
+import com.alexstyl.specialdates.theming.Themer;
+import com.alexstyl.specialdates.transition.FadeInTransition;
+import com.alexstyl.specialdates.transition.FadeOutTransition;
+import com.alexstyl.specialdates.transition.SimpleTransitionListener;
+import com.alexstyl.specialdates.ui.ViewFader;
+import com.alexstyl.specialdates.ui.base.MementoActivity;
+import com.alexstyl.specialdates.ui.widget.SpacesItemDecoration;
+import com.novoda.notils.caster.Views;
+import com.novoda.notils.meta.AndroidUtils;
-public class SearchActivity extends ThemedActivity {
+import static android.view.View.GONE;
+
+/**
+ * A fragment in which the user can search for namedays and their contact's birthdays.
+ *
The fragment has a different logic for when the user has enabled namedays for any language.
+ * If the user has enabled to display Namedays, the search EditText will give no suggestions. Instead a custom
+ * suggestion bar on top of the keyboard is going to be given to the user with names.
+ * Created by alexstyl on 20/04/15.
+ */
+public class SearchActivity extends MementoActivity {
+
+ private static final String KEY_QUERY = "alexstyl:key_query";
+ private static final int ID_CONTACTS = 31;
+ private static final int ID_NAMEDAYS = 32;
+ private static final int INITAL_COUNT = 5;
+
+ private int searchCounter = INITAL_COUNT;
+ private SearchBar searchbar;
+ private RecyclerView resultView;
+ private RecyclerView namesSuggestionsView;
+ private SearchResultAdapter adapter;
+ private NameSuggestionsAdapter namesAdapter;
+ private String searchQuery;
+
+ private ViewFader fader = new ViewFader();
+ private ViewGroup content;
+ private NamedayPreferences namedayPreferences;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ Themer themer = Themer.get(this);
+ themer.initialiseActivity(this);
setContentView(R.layout.activity_search);
+ Firebase.get(this).trackScreen(Screen.SEARCH);
+ searchbar = Views.findById(this, R.id.search_searchbar);
+ setSupportActionBar(searchbar);
+ content = Views.findById(this, R.id.search_content);
+ resultView = Views.findById(this, android.R.id.list);
+ resultView.setHasFixedSize(false);
+ namesSuggestionsView = Views.findById(this, R.id.nameday_suggestions);
+
+ if (savedInstanceState != null) {
+ searchQuery = savedInstanceState.getString(KEY_QUERY);
+ }
+
+ setupSearchField();
+
+ ImageLoader imageLoader = ImageLoader.createSquareThumbnailLoader(getResources());
+ int year = DayDate.today().getYear();
+ NamedayLocale locale = NamedayPreferences.newInstance(this).getSelectedLanguage();
+ NamedayCalendar namedayCalendar = NamedayCalendarProvider.newInstance(this).loadNamedayCalendarForLocale(locale, year);
+
+ adapter = new SearchResultAdapter(imageLoader, namedayCalendar);
+ adapter.setSearchResultClickListener(listener);
+
+ resultView.setHasFixedSize(true);
+ RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context());
+ int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.card_spacing_between);
+ resultView.addItemDecoration(new SpacesItemDecoration(spacingInPixels, 3));
+ resultView.setLayoutManager(mLayoutManager);
+ resultView.setAdapter(adapter);
+
+ searchbar.setOnBackKeyPressedListener(onBackKeyPressedListener);
+
+ namedayPreferences = NamedayPreferences.newInstance(this);
+ setupSearchbarHint(namedayPreferences);
+
+ if (namedayPreferences.isEnabled()) {
+ // we are loading namedays as well
+ GridLayoutManager namedayManager = new GridLayoutManager(context(), 1, RecyclerView.HORIZONTAL, false);
+ namesAdapter = NameSuggestionsAdapter.newInstance(context());
+ namesAdapter.setOnNameSelectedListener(onNameSelectedListener);
+ namesSuggestionsView.setHasFixedSize(true);
+ namesSuggestionsView.setLayoutManager(namedayManager);
+ namesSuggestionsView.setAdapter(namesAdapter);
+
+ searchbar.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
+ searchbar.setOnFocusChangeListener(new ToggleVisibilityOnFocus(namesSuggestionsView));
+ } else {
+ namesSuggestionsView.setVisibility(GONE);
+ }
+
+ if (savedInstanceState == null) {
+ fader.hideContentOf(searchbar);
+ ViewTreeObserver viewTreeObserver = searchbar.getViewTreeObserver();
+ viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ searchbar.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ animateShowSearch();
+ }
+
+ private void animateShowSearch() {
+ TransitionManager.beginDelayedTransition(searchbar, FadeInTransition.createTransition());
+ fader.showContent(searchbar);
+ }
+ });
+ }
+
+ }
+
+ private void setupSearchbarHint(NamedayPreferences preferences) {
+ SearchHintCreator searchHintCreator = new SearchHintCreator(getResources(), preferences);
+ searchbar.setHint(searchHintCreator.createHint());
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_search, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ super.onPrepareOptionsMenu(menu);
+ MenuItem clearMenuItem = menu.findItem(R.id.action_clear);
+ clearMenuItem.setVisible(searchbar.hasText());
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ case R.id.action_clear:
+ onClearPressed();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void finish() {
+ if (supportsTransitions()) {
+ AndroidUtils.requestHideKeyboard(this, searchbar);
+ exitTransitionWithAction(new Runnable() {
+ @Override
+ public void run() {
+ SearchActivity.super.finish();
+ overridePendingTransition(0, 0);
+ }
+ });
+ } else {
+ super.finish();
+ }
+ }
+
+ private void exitTransitionWithAction(final Runnable endingAction) {
+ Transition transition = FadeOutTransition.withAction(new SimpleTransitionListener() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ endingAction.run();
+ }
+ });
+
+ TransitionManager.beginDelayedTransition(searchbar, transition);
+ fader.hideContentOf(searchbar);
+
+ TransitionManager.beginDelayedTransition(content, new Fade(Fade.OUT));
}
+ private void onClearPressed() {
+ searchbar.clearText();
+ AndroidUtils.toggleKeyboard(this);
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putString(KEY_QUERY, searchQuery);
+ }
+
+ private void startSearching() {
+ getSupportLoaderManager().restartLoader(ID_CONTACTS, null, contactSearchCallbacks);
+ getSupportLoaderManager().restartLoader(ID_NAMEDAYS, null, namedayLoaderCallbacks);
+ }
+
+ private void clearResults() {
+ adapter.clearResults();
+ if (namedayPreferences.isEnabled()) {
+ namesAdapter.clearNames();
+ }
+ }
+
+ private void resetSearchCounter() {
+ searchCounter = INITAL_COUNT;
+ }
+
+ private void updateNameSuggestions(String text) {
+ if (namedayPreferences.isEnabled()) {
+ namesAdapter.getFilter().filter(text);
+ }
+ }
+
+ private void setupSearchField() {
+ searchbar.addTextWatcher(DelayedTextWatcher.newInstance(textUpdatedTextUpdatedCallback));
+ }
+
+ private void onNameSet(String name) {
+ // setting the text to the EditText will trigger the search for the name
+ AndroidUtils.requestHideKeyboard(this, searchbar);
+ searchbar.setText(name);
+ searchbar.clearFocus();
+ if (namedayPreferences.isEnabled()) {
+ namesAdapter.clearNames();
+ }
+ }
+
+ private final NameSuggestionsAdapter.OnNameSelectedListener onNameSelectedListener = new NameSuggestionsAdapter.OnNameSelectedListener() {
+ @Override
+ public void onNameSelected(View view, String name) {
+ onNameSet(name);
+ }
+ };
+
+ private final SearchResultAdapter.SearchResultClickListener listener = new SearchResultAdapter.SearchResultClickListener() {
+
+ @Override
+ public void onContactClicked(View v, Contact contact) {
+ contact.displayQuickInfo(context(), v);
+ }
+
+ @Override
+ public void onNamedayClicked(View v, int month, int day) {
+ DayDate dayDate = DayDate.today();
+ DateDetailsActivity.startActivity(context(), month, day, dayDate.getYear());
+ }
+
+ };
+
+ private final LoaderManager.LoaderCallbacks namedayLoaderCallbacks = new LoaderManager.LoaderCallbacks() {
+
+ @Override
+ public Loader onCreateLoader(int id, Bundle args) {
+ return NamedaysLoader.newInstance(context(), searchQuery);
+ }
+
+ @Override
+ public void onLoadFinished(Loader loader, NameCelebrations results) {
+ adapter.setNamedays(results);
+ }
+
+ @Override
+ public void onLoaderReset(Loader loader) {
+ adapter.setNamedays(NameCelebrations.EMPTY);
+ }
+ };
+
+ private final DelayedTextWatcher.TextUpdatedCallback textUpdatedTextUpdatedCallback = new DelayedTextWatcher.TextUpdatedCallback() {
+ @Override
+ public void onTextChanged(String text) {
+ searchQuery = text;
+ updateNameSuggestions(text);
+ resetSearchCounter();
+ invalidateOptionsMenu();
+ }
+
+ @Override
+ public void onEmptyTextConfirmed() {
+ clearResults();
+ invalidateOptionsMenu();
+ }
+
+ @Override
+ public void onTextConfirmed(String text) {
+ startSearching();
+ }
+ };
+
+ private final LoaderManager.LoaderCallbacks contactSearchCallbacks = new LoaderManager.LoaderCallbacks() {
+
+ @Override
+ public Loader onCreateLoader(int id, Bundle args) {
+ adapter.notifyIsLoadingMore();
+ return new SearchLoader(context(), searchQuery, searchCounter);
+ }
+
+ @Override
+ public void onLoadFinished(Loader loader, SearchResults searchResults) {
+ if (loader.getId() == ID_CONTACTS) {
+ adapter.updateSearchResults(searchResults);
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader loader) {
+ if (loader.getId() == ID_CONTACTS) {
+ adapter.notifyIsLoadingMore();
+ }
+ }
+ };
+
+ private final OnBackKeyPressedListener onBackKeyPressedListener = new OnBackKeyPressedListener() {
+ @Override
+ public boolean onBackButtonPressed() {
+ if (searchbar.hasText()) {
+ // do nothing
+ return false;
+ } else {
+ finish();
+ return true;
+ }
+ }
+ };
+
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchBar.java b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchBar.java
new file mode 100644
index 00000000..79c0e3aa
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchBar.java
@@ -0,0 +1,81 @@
+package com.alexstyl.specialdates.search;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.text.TextWatcher;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.TextView;
+
+import com.alexstyl.specialdates.R;
+import com.alexstyl.specialdates.theming.AttributeExtractor;
+import com.alexstyl.specialdates.theming.ViewTinter;
+import com.novoda.notils.caster.Views;
+
+public class SearchBar extends Toolbar {
+
+ private BackKeyEditText editText;
+
+ public SearchBar(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ inflate(getContext(), R.layout.merge_searchbar, this);
+ editText = Views.findById(this, R.id.toolbar_search_edittext);
+ setBackgroundColor(Color.WHITE);
+ addTintedUpNavigation();
+
+ editText.setOnEditorActionListener(onEditorActionListener);
+ }
+
+ private void addTintedUpNavigation() {
+ ViewTinter viewTinter = new ViewTinter(new AttributeExtractor());
+ Drawable backDrawable = getResources().getDrawable(R.drawable.ic_action_arrow_light_back).mutate();
+ Drawable tintedUpDrawable = viewTinter.createAccentTintedDrawable(backDrawable, getContext());
+ setNavigationIcon(tintedUpDrawable);
+ }
+
+ public void addTextWatcher(TextWatcher textWatcher) {
+ editText.addTextChangedListener(textWatcher);
+ }
+
+ public void setInputType(int typeTextFlag) {
+ editText.setInputType(typeTextFlag);
+ }
+
+ private final TextView.OnEditorActionListener onEditorActionListener = new TextView.OnEditorActionListener() {
+ @Override
+ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+ if (actionId == EditorInfo.IME_ACTION_SEARCH) {
+ InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
+ editText.requestFocus();
+ return true;
+ }
+ return false;
+ }
+ };
+
+ public void setOnBackKeyPressedListener(OnBackKeyPressedListener listener) {
+ editText.setOnBackKeyPressedListener(listener);
+ }
+
+ public void setText(String text) {
+ editText.setText(text);
+ }
+
+ public void clearText() {
+ editText.setText(null);
+ }
+
+ public boolean hasText() {
+ return editText.length() > 0;
+ }
+
+ public void setHint(String hint) {
+ editText.setHint(hint);
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchHintCreator.java b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchHintCreator.java
new file mode 100644
index 00000000..c2ae9702
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchHintCreator.java
@@ -0,0 +1,26 @@
+package com.alexstyl.specialdates.search;
+
+import android.content.res.Resources;
+
+import com.alexstyl.specialdates.R;
+import com.alexstyl.specialdates.events.namedays.NamedayPreferences;
+
+public class SearchHintCreator {
+
+ private final Resources resources;
+ private final NamedayPreferences namedayPreferences;
+
+ public SearchHintCreator(Resources resources, NamedayPreferences namedayPreferences) {
+ this.resources = resources;
+ this.namedayPreferences = namedayPreferences;
+ }
+
+ public String createHint() {
+ boolean enabled = namedayPreferences.isEnabled();
+ if (enabled) {
+ return resources.getString(R.string.search_hint_contacts_and_namedays);
+ } else {
+ return resources.getString(R.string.search_hint_contacts);
+ }
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultAdapter.java b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultAdapter.java
index 53a17d7f..6cff3770 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultAdapter.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultAdapter.java
@@ -1,51 +1,32 @@
package com.alexstyl.specialdates.search;
-import android.content.Context;
-import android.content.res.Resources;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import com.alexstyl.specialdates.contact.Contact;
-import com.alexstyl.specialdates.date.DayDate;
+import com.alexstyl.specialdates.events.namedays.NameCelebrations;
import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendar;
-import com.alexstyl.specialdates.events.namedays.calendar.NamedayCalendarProvider;
-import com.alexstyl.specialdates.events.namedays.NamedayLocale;
-import com.alexstyl.specialdates.events.namedays.NamedayPreferences;
import com.alexstyl.specialdates.images.ImageLoader;
-import com.alexstyl.specialdates.events.namedays.NameCelebrations;
import com.novoda.notils.exception.DeveloperError;
import java.util.ArrayList;
import java.util.List;
-public class SearchResultAdapter extends RecyclerView.Adapter {
+public final class SearchResultAdapter extends RecyclerView.Adapter {
private final List contacts = new ArrayList<>();
private NamedayCard namedayCard = new NamedayCard();
private boolean isLoadingMore;
- private final boolean namedayEnabled;
private boolean canLoadMore = false;
private final ImageLoader imageLoader;
private final NamedayCalendar namedayCalendar;
private String searchQuery;
- public static SearchResultAdapter newInstance(Context context, boolean loadNamedays) {
- Resources resources = context.getResources();
- ImageLoader imageLoader = ImageLoader.createSquareThumbnailLoader(resources);
-
- int year = DayDate.today().getYear();
- NamedayLocale locale = NamedayPreferences.newInstance(context).getSelectedLanguage();
- NamedayCalendar namedayCalendar = NamedayCalendarProvider.newInstance(context)
- .loadNamedayCalendarForLocale(locale, year);
- return new SearchResultAdapter(loadNamedays, imageLoader, namedayCalendar);
- }
-
- private SearchResultAdapter(boolean loadNamedays, ImageLoader imageLoader, NamedayCalendar namedayCalendar) {
- this.namedayEnabled = loadNamedays;
+ SearchResultAdapter(ImageLoader imageLoader, NamedayCalendar namedayCalendar) {
this.imageLoader = imageLoader;
this.namedayCalendar = namedayCalendar;
}
@@ -141,7 +122,7 @@ private boolean containsNoResults() {
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == VIEWTYPE_CONTACTVIEW) {
- return SearchResultContactViewHolder.createFor(parent, namedayCalendar, imageLoader, namedayEnabled);
+ return SearchResultContactViewHolder.createFor(parent, namedayCalendar, imageLoader);
}
if (viewType == VIEWTYPE_NAMEDAYS_VIEW) {
return SearchResultNamedayViewHolder.createFor(parent);
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultContactViewHolder.java b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultContactViewHolder.java
index aca93e8a..5d272da4 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultContactViewHolder.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/SearchResultContactViewHolder.java
@@ -25,22 +25,19 @@ class SearchResultContactViewHolder extends RecyclerView.ViewHolder {
private final TextView nameday;
private final ImageLoader imageLoader;
- private boolean namedayEnabled;
public static SearchResultContactViewHolder createFor(ViewGroup parent,
NamedayCalendar namedayCalendar,
- ImageLoader imageLoader,
- boolean namedayEnabled) {
+ ImageLoader imageLoader) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.row_search_result_contact, parent, false);
- return new SearchResultContactViewHolder(view, namedayCalendar, imageLoader, namedayEnabled);
+ return new SearchResultContactViewHolder(view, namedayCalendar, imageLoader);
}
- SearchResultContactViewHolder(View convertView, NamedayCalendar namedayCalendar, ImageLoader imageLoader, boolean namedayEnabled) {
+ SearchResultContactViewHolder(View convertView, NamedayCalendar namedayCalendar, ImageLoader imageLoader) {
super(convertView);
this.namedayCalendar = namedayCalendar;
this.imageLoader = imageLoader;
- this.namedayEnabled = namedayEnabled;
this.displayName = (TextView) convertView.findViewById(R.id.contact_name);
this.birthday = (TextView) convertView.findViewById(R.id.birthday_label);
this.nameday = (TextView) convertView.findViewById(R.id.nameday_label);
@@ -59,15 +56,12 @@ void bind(final Contact contact, final SearchResultAdapter.SearchResultClickList
bindNamedays(contact);
itemView.setOnClickListener(
- new View.OnClickListener()
-
- {
+ new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onContactClicked(v, contact);
}
}
-
);
}
@@ -122,7 +116,7 @@ private static String getEventString(Context context, int stringRes, DayDate dat
}
private boolean noEventsToDisplay(NameCelebrations namedays) {
- return !namedayEnabled || namedays.containsNoDate();
+ return namedays.containsNoDate();
}
private Context getContext() {
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/search/ToggleVisibilityOnFocus.java b/mobile/src/main/java/com/alexstyl/specialdates/search/ToggleVisibilityOnFocus.java
new file mode 100644
index 00000000..be59a052
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/search/ToggleVisibilityOnFocus.java
@@ -0,0 +1,23 @@
+package com.alexstyl.specialdates.search;
+
+import android.view.View;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+public class ToggleVisibilityOnFocus implements View.OnFocusChangeListener {
+ private final View view;
+
+ public ToggleVisibilityOnFocus(View view) {
+ this.view = view;
+ }
+
+ @Override
+ public void onFocusChange(View v, boolean hasFocus) {
+ if (hasFocus) {
+ view.setVisibility(VISIBLE);
+ } else {
+ view.setVisibility(GONE);
+ }
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceActivity.java
index e673df7f..3f97282d 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceActivity.java
@@ -25,7 +25,7 @@ public class MainPreferenceActivity extends MementoPreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Themer.get().initialiseActivity(this);
+ Themer.get(this).initialiseActivity(this);
setContentView(R.layout.activity_settings);
MementoToolbar toolbar = Views.findById(this, R.id.memento_toolbar);
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceFragment.java b/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceFragment.java
index 97c27a30..16001d42 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceFragment.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/settings/MainPreferenceFragment.java
@@ -24,7 +24,8 @@ final public class MainPreferenceFragment extends MementoPreferenceFragment {
private ListPreference namedayLanguageListPreferences;
private NamedayPreferences namedaysPreferences;
- private ThemingPreferences themingPreferences = new ThemingPreferences();
+ private ThemingPreferences themingPreferences;
+
private Preference appThemePreference;
private MainPreferenceActivity activity;
@@ -42,6 +43,7 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference_main);
analytics = Firebase.get(getActivity());
+ themingPreferences = ThemingPreferences.newInstance(getActivity());
Preference bankholidaysLanguage = findPreference(R.string.key_bankholidays_language);
bankholidaysLanguage.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/support/RateDialog.java b/mobile/src/main/java/com/alexstyl/specialdates/support/RateDialog.java
index 74752226..cfe9c725 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/support/RateDialog.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/support/RateDialog.java
@@ -10,6 +10,7 @@
import com.alexstyl.specialdates.Navigator;
import com.alexstyl.specialdates.R;
+import com.alexstyl.specialdates.analytics.Firebase;
import com.alexstyl.specialdates.ui.base.MementoActivity;
import com.novoda.notils.caster.Views;
@@ -17,17 +18,18 @@ public class RateDialog extends MementoActivity {
private final String smiley = " " + Emoticon.SMILEY.asText();
private AskForSupport askForSupport;
+ private Navigator navigator;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rate_dialog);
askForSupport = new AskForSupport(context());
-
+ navigator = new Navigator(this, Firebase.get(this));
Views.findById(this, R.id.support_rate_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- new Navigator(v.getContext()).toPlayStore();
+ navigator.toPlayStore();
Toast.makeText(context(), R.string.support_thanks_for_rating, Toast.LENGTH_LONG).show();
askForSupport.onRateEnd();
finish();
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/support/SupportDonateDialog.java b/mobile/src/main/java/com/alexstyl/specialdates/support/SupportDonateDialog.java
index 7426cdb6..ef3c211d 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/support/SupportDonateDialog.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/support/SupportDonateDialog.java
@@ -216,8 +216,4 @@ public void onDestroy() {
}
}
- public static void displayDialog(Context context) {
- Intent intent = new Intent(context, SupportDonateDialog.class);
- context.startActivity(intent);
- }
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/support/SupportTranslateDialog.java b/mobile/src/main/java/com/alexstyl/specialdates/support/SupportTranslateDialog.java
index eac9b76a..ebb00911 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/support/SupportTranslateDialog.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/support/SupportTranslateDialog.java
@@ -1,8 +1,6 @@
package com.alexstyl.specialdates.support;
-import android.annotation.TargetApi;
import android.content.Context;
-import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
@@ -10,7 +8,6 @@
import com.alexstyl.specialdates.R;
import com.alexstyl.specialdates.theming.Themer;
import com.alexstyl.specialdates.ui.base.ThemedActivity;
-import com.alexstyl.specialdates.util.Utils;
import com.novoda.notils.caster.Views;
public class SupportTranslateDialog extends ThemedActivity {
@@ -19,7 +16,7 @@ public class SupportTranslateDialog extends ThemedActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.dialog_translate, Themer.get().getCurrentTheme());
+ setContentView(R.layout.dialog_translate, Themer.get(this).getCurrentTheme());
Views.findById(this, android.R.id.content).setBackgroundColor(getResources().getColor(android.R.color.transparent));
Views.findById(this, R.id.button_ok).setOnClickListener(new View.OnClickListener() {
@@ -38,18 +35,10 @@ public void onClick(View v) {
}
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
public boolean copyLinkToClipboard() {
- if (Utils.hasHoneycomb()) {
- android.content.ClipboardManager clipboard = (android.content.ClipboardManager)
- getSystemService(Context.CLIPBOARD_SERVICE);
- android.content.ClipData clip = android.content.ClipData
- .newPlainText(getResources().getString(R.string.app_name), getString(R.string.link_translate_short));
- clipboard.setPrimaryClip(clip);
- } else {
- android.text.ClipboardManager clipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
- clipboard.setText(getString(R.string.link_translate_short));
- }
+ android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+ android.content.ClipData clip = android.content.ClipData.newPlainText(getResources().getString(R.string.app_name), getString(R.string.link_translate_short));
+ clipboard.setPrimaryClip(clip);
return true;
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/theming/Themer.java b/mobile/src/main/java/com/alexstyl/specialdates/theming/Themer.java
index 1c135be0..7531406e 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/theming/Themer.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/theming/Themer.java
@@ -14,9 +14,10 @@ public class Themer {
private static Themer INSTANCE;
- public static Themer get() {
+ public static Themer get(Context context) {
if (INSTANCE == null) {
- INSTANCE = new Themer(new ThemingPreferences(), new AttributeExtractor());
+ ThemingPreferences preferences = ThemingPreferences.newInstance(context);
+ INSTANCE = new Themer(preferences, new AttributeExtractor());
}
return INSTANCE;
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/theming/ThemingPreferences.java b/mobile/src/main/java/com/alexstyl/specialdates/theming/ThemingPreferences.java
index fc55ace3..47f1ce9d 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/theming/ThemingPreferences.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/theming/ThemingPreferences.java
@@ -1,16 +1,21 @@
package com.alexstyl.specialdates.theming;
+import android.content.Context;
+
import com.alexstyl.specialdates.EasyPreferences;
-import com.alexstyl.specialdates.MementoApplication;
import com.alexstyl.specialdates.R;
-public class ThemingPreferences {
+public final class ThemingPreferences {
private static final String DEFAULT_THEME = MementoTheme.CHERRY_RED.getThemeName();
private final EasyPreferences preferences;
- public ThemingPreferences() {
- this.preferences = EasyPreferences.createForDefaultPreferences(MementoApplication.getAppContext());
+ public static ThemingPreferences newInstance(Context context) {
+ return new ThemingPreferences(EasyPreferences.createForDefaultPreferences(context));
+ }
+
+ private ThemingPreferences(EasyPreferences defaultPreferences) {
+ this.preferences = defaultPreferences;
}
public MementoTheme getSelectedTheme() {
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/theming/ViewTinter.java b/mobile/src/main/java/com/alexstyl/specialdates/theming/ViewTinter.java
new file mode 100644
index 00000000..5bab4e53
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/theming/ViewTinter.java
@@ -0,0 +1,19 @@
+package com.alexstyl.specialdates.theming;
+
+import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+
+public class ViewTinter {
+ private final AttributeExtractor extractor;
+
+ public ViewTinter(AttributeExtractor extractor) {
+ this.extractor = extractor;
+ }
+
+ public Drawable createAccentTintedDrawable(Drawable mutate, Context context) {
+ int accentColor = extractor.extractAccentColorFrom(context);
+ mutate.setColorFilter(accentColor, PorterDuff.Mode.SRC_IN);
+ return mutate;
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeInTransition.java b/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeInTransition.java
new file mode 100644
index 00000000..eb363f12
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeInTransition.java
@@ -0,0 +1,19 @@
+package com.alexstyl.specialdates.transition;
+
+import android.support.transition.AutoTransition;
+import android.support.transition.Transition;
+
+public class FadeInTransition extends AutoTransition {
+
+ private static final int FADE_IN_DURATION = 200;
+
+ private FadeInTransition() {
+ // force callers to call the factory method to instantiate this class
+ }
+
+ public static Transition createTransition() {
+ AutoTransition transition = new AutoTransition();
+ transition.setDuration(FADE_IN_DURATION);
+ return transition;
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeOutTransition.java b/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeOutTransition.java
new file mode 100644
index 00000000..04632563
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/transition/FadeOutTransition.java
@@ -0,0 +1,25 @@
+package com.alexstyl.specialdates.transition;
+
+import android.support.transition.AutoTransition;
+import android.support.transition.Transition;
+
+public class FadeOutTransition extends AutoTransition {
+
+ private FadeOutTransition() {
+ // force callers to call the factory method to instantiate this class
+ }
+
+ private static final int FADE_OUT_DURATION = 250;
+
+ /**
+ * Creates a AutoTransition that calls the {@linkplain Transition.TransitionListener#onTransitionEnd(Transition)}
+ * of the passing Listener when complete
+ */
+ public static Transition withAction(TransitionListener finishingAction) {
+ AutoTransition transition = new AutoTransition();
+ transition.setDuration(FADE_OUT_DURATION);
+ transition.addListener(finishingAction);
+ return transition;
+ }
+
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/transition/SimpleTransitionListener.java b/mobile/src/main/java/com/alexstyl/specialdates/transition/SimpleTransitionListener.java
new file mode 100644
index 00000000..570412cf
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/transition/SimpleTransitionListener.java
@@ -0,0 +1,32 @@
+package com.alexstyl.specialdates.transition;
+
+import android.support.transition.Transition;
+
+import static android.support.transition.Transition.TransitionListener;
+
+public class SimpleTransitionListener implements TransitionListener {
+ @Override
+ public void onTransitionStart(Transition transition) {
+ // do nothing
+ }
+
+ @Override
+ public void onTransitionPause(Transition transition) {
+ // do nothing
+ }
+
+ @Override
+ public void onTransitionResume(Transition transition) {
+ // do nothing
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ // do nothing
+ }
+
+ @Override
+ public void onTransitionCancel(Transition transition) {
+ // do nothing
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeMonitor.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeMonitor.java
new file mode 100644
index 00000000..0876953d
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeMonitor.java
@@ -0,0 +1,25 @@
+package com.alexstyl.specialdates.ui;
+
+import com.alexstyl.specialdates.theming.MementoTheme;
+import com.alexstyl.specialdates.theming.ThemingPreferences;
+
+public final class ThemeMonitor {
+
+ private final MementoTheme theme;
+ private final ThemingPreferences preferences;
+
+ public static ThemeMonitor startMonitoring(ThemingPreferences preferences) {
+ MementoTheme currentTheme = preferences.getSelectedTheme();
+ return new ThemeMonitor(currentTheme, preferences);
+ }
+
+ private ThemeMonitor(MementoTheme theme, ThemingPreferences preferences) {
+ this.theme = theme;
+ this.preferences = preferences;
+ }
+
+ public boolean hasThemeChanged() {
+ MementoTheme newTheme = preferences.getSelectedTheme();
+ return newTheme != theme;
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeReapplier.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeReapplier.java
deleted file mode 100644
index 4d1106ae..00000000
--- a/mobile/src/main/java/com/alexstyl/specialdates/ui/ThemeReapplier.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.alexstyl.specialdates.ui;
-
-import android.content.Context;
-
-import com.alexstyl.specialdates.theming.MementoTheme;
-import com.alexstyl.specialdates.theming.ThemingPreferences;
-
-public class ThemeReapplier {
-
- private final Context context;
-
- private final MementoTheme theme;
- private final ThemingPreferences themingPreferences;
-
- public ThemeReapplier(Context context) {
- this.context = context.getApplicationContext();
- this.themingPreferences = new ThemingPreferences();
- this.theme = themingPreferences.getSelectedTheme();
- }
-
- public boolean hasThemeChanged() {
- MementoTheme newTheme = themingPreferences.getSelectedTheme();
- return newTheme != theme;
- }
-}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/ViewFader.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/ViewFader.java
new file mode 100644
index 00000000..1f7a78c8
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/ViewFader.java
@@ -0,0 +1,22 @@
+package com.alexstyl.specialdates.ui;
+
+import android.view.ViewGroup;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+public final class ViewFader {
+
+ public void hideContentOf(ViewGroup viewGroup) {
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ viewGroup.getChildAt(i).setVisibility(GONE);
+ }
+ }
+
+ public void showContent(ViewGroup viewGroup) {
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ viewGroup.getChildAt(i).setVisibility(VISIBLE);
+ }
+ }
+
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/activity/MainActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/activity/MainActivity.java
index 3d65b75e..ee77b367 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/ui/activity/MainActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/activity/MainActivity.java
@@ -1,28 +1,32 @@
package com.alexstyl.specialdates.ui.activity;
-import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
-import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
+import com.alexstyl.specialdates.Navigator;
import com.alexstyl.specialdates.R;
-import com.alexstyl.specialdates.about.AboutActivity;
-import com.alexstyl.specialdates.addevent.AddBirthdayActivity;
-import com.alexstyl.specialdates.analytics.Analytics;
import com.alexstyl.specialdates.analytics.Firebase;
import com.alexstyl.specialdates.analytics.Screen;
-import com.alexstyl.specialdates.settings.MainPreferenceActivity;
+import com.alexstyl.specialdates.events.namedays.NamedayPreferences;
+import com.alexstyl.specialdates.search.SearchHintCreator;
import com.alexstyl.specialdates.support.AskForSupport;
import com.alexstyl.specialdates.support.SupportDonateDialog;
-import com.alexstyl.specialdates.ui.ThemeReapplier;
+import com.alexstyl.specialdates.theming.ThemingPreferences;
+import com.alexstyl.specialdates.ui.ThemeMonitor;
+import com.alexstyl.specialdates.ui.ViewFader;
import com.alexstyl.specialdates.ui.base.ThemedActivity;
-import com.alexstyl.specialdates.upcoming.UpcomingEventsFragment;
+import com.alexstyl.specialdates.upcoming.ExposedSearchToolbar;
+import com.alexstyl.specialdates.upcoming.SearchTransitioner;
import com.alexstyl.specialdates.util.Notifier;
import com.alexstyl.specialdates.widgetprovider.TodayWidgetProvider;
import com.novoda.notils.caster.Views;
+import com.novoda.notils.meta.AndroidUtils;
+
+import static android.view.View.OnClickListener;
/*
* The activity was first launched with MainActivity being in package.ui.activity
@@ -31,49 +35,50 @@
public class MainActivity extends ThemedActivity {
private Notifier notifier;
- private UpcomingEventsFragment upcomingEventsFragment;
private AskForSupport askForSupport;
- private ThemeReapplier reapplier;
- private Analytics analytics;
+ private ThemeMonitor themeMonitor;
+
+ private Navigator navigator;
+
+ private SearchTransitioner searchTransitioner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- reapplier = new ThemeReapplier(this);
- analytics = Firebase.get(this);
+ themeMonitor = ThemeMonitor.startMonitoring(ThemingPreferences.newInstance(this));
+ Firebase analytics = Firebase.get(this);
analytics.trackScreen(Screen.HOME);
- Toolbar toolbar = Views.findById(this, R.id.memento_toolbar);
+ navigator = new Navigator(this, analytics);
+
+ ExposedSearchToolbar toolbar = Views.findById(this, R.id.memento_toolbar);
+ toolbar.setOnClickListener(onToolbarClickListener);
setSupportActionBar(toolbar);
+ ViewGroup activityContent = Views.findById(this, R.id.main_content);
+ searchTransitioner = new SearchTransitioner(this, navigator, activityContent, toolbar, new ViewFader());
+
notifier = Notifier.newInstance(this);
- FloatingActionButton floatingActionButton = Views.findById(this, R.id.fab_add);
- floatingActionButton.setOnClickListener(startAddBirthdayOnClick);
+ FloatingActionButton addBirthdayFAB = Views.findById(this, R.id.main_birthday_add_fab);
+ addBirthdayFAB.setOnClickListener(startAddBirthdayOnClick);
askForSupport = new AskForSupport(this);
- upcomingEventsFragment = (UpcomingEventsFragment) getSupportFragmentManager().findFragmentById(R.id.upcoming);
+
+ SearchHintCreator hintCreator = new SearchHintCreator(getResources(), NamedayPreferences.newInstance(this));
+ setTitle(hintCreator.createHint());
}
@Override
protected void onResume() {
super.onResume();
- if (reapplier.hasThemeChanged()) {
+ if (themeMonitor.hasThemeChanged()) {
reapplyTheme();
} else if (askForSupport.shouldAskForRating()) {
askForSupport.askForRatingFromUser(this);
}
- }
-
- @Override
- protected void onPostResume() {
- super.onPostResume();
- }
-
- private void startAddBirthdayActivity() {
- Intent intent = new Intent(this, AddBirthdayActivity.class);
- startActivity(intent);
+ searchTransitioner.onActivityResumed();
}
@Override
@@ -89,37 +94,22 @@ public boolean onCreateOptionsMenu(Menu menu) {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
- openSettings();
+ navigator.toSettings();
break;
case R.id.action_about:
- openAboutScreen();
+ navigator.toAbout();
break;
case R.id.action_donate:
- openDonateDialog();
+ navigator.toDonateDialog();
break;
}
return super.onOptionsItemSelected(item);
}
- private void openDonateDialog() {
- analytics.trackScreen(Screen.DONATE);
- SupportDonateDialog.displayDialog(this);
- }
-
- private void openAboutScreen() {
- analytics.trackScreen(Screen.ABOUT);
- startActivity(new Intent(this, AboutActivity.class));
-
- }
-
- private void openSettings() {
- analytics.trackScreen(Screen.SETTINGS);
- startActivity(new Intent(this, MainPreferenceActivity.class));
- }
-
@Override
public boolean onSearchRequested() {
- return upcomingEventsFragment.onSearchRequested();
+ searchTransitioner.transitionToSearch();
+ return true;
}
@Override
@@ -136,10 +126,19 @@ protected void onDestroy() {
}
}
- private final View.OnClickListener startAddBirthdayOnClick = new View.OnClickListener() {
+ private final OnClickListener onToolbarClickListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ AndroidUtils.toggleKeyboard(v.getContext());
+ onSearchRequested();
+ }
+
+ };
+
+ private final OnClickListener startAddBirthdayOnClick = new OnClickListener() {
@Override
public void onClick(View v) {
- startAddBirthdayActivity();
+ navigator.toAddBirthday();
}
};
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/base/MementoActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/base/MementoActivity.java
index ec2c5c07..13872a4d 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/ui/base/MementoActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/base/MementoActivity.java
@@ -7,6 +7,7 @@
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
+import com.alexstyl.specialdates.util.Utils;
import com.novoda.notils.exception.DeveloperError;
public class MementoActivity extends AppCompatActivity {
@@ -61,4 +62,8 @@ protected Context context() {
return this;
}
+ protected boolean supportsTransitions() {
+ return Utils.hasKitKat();
+ }
+
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/base/ThemedActivity.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/base/ThemedActivity.java
index db0fe1c0..411f3313 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/ui/base/ThemedActivity.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/base/ThemedActivity.java
@@ -13,7 +13,7 @@ public class ThemedActivity extends MementoActivity {
@Override
public void setContentView(@LayoutRes int layoutResID) {
- Themer.get().initialiseActivity(this);
+ Themer.get(this).initialiseActivity(this);
super.setContentView(layoutResID);
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/ui/widget/MementoToolbar.java b/mobile/src/main/java/com/alexstyl/specialdates/ui/widget/MementoToolbar.java
index 2f187911..3a7697fb 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/ui/widget/MementoToolbar.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/ui/widget/MementoToolbar.java
@@ -24,7 +24,7 @@ public MementoToolbar(Context context, @Nullable AttributeSet attrs) {
if (isInEditMode()) {
return;
}
- themer = Themer.get();
+ themer = Themer.get(context);
int toolbarColor = fetchAccentColor(context);
float toolbarElevation = getToolbarElevation();
@@ -50,7 +50,7 @@ public float getToolbarElevation() {
public void displayAsUp() {
if (themer.isActivityUsingDarkIcons(getContext())) {
- setNavigationIcon(R.drawable.ic_action_arrow_dark_back);
+ setNavigationIcon(R.drawable.ic_action_left_semitransparent);
} else {
setNavigationIcon(R.drawable.ic_action_arrow_light_back);
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ExposedSearchToolbar.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ExposedSearchToolbar.java
new file mode 100644
index 00000000..2f119a19
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ExposedSearchToolbar.java
@@ -0,0 +1,18 @@
+package com.alexstyl.specialdates.upcoming;
+
+import android.content.Context;
+import android.support.v7.widget.Toolbar;
+import android.util.AttributeSet;
+
+import com.alexstyl.specialdates.R;
+
+public class ExposedSearchToolbar extends Toolbar {
+
+ public ExposedSearchToolbar(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ setBackgroundResource(R.drawable.card_noshadow);
+ setNavigationIcon(R.drawable.ic_action_search);
+ }
+
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/MonthTitleSetter.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/MonthTitleSetter.java
deleted file mode 100644
index 8ec4c9f9..00000000
--- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/MonthTitleSetter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.alexstyl.specialdates.upcoming;
-
-import android.app.Activity;
-
-import java.util.Locale;
-
-class MonthTitleSetter {
-
- private final Activity activity;
- private final MonthLabels monthLabels;
-
-
- public static MonthTitleSetter createSetterFor(Activity activity) {
- MonthLabels monthLabels = MonthLabels.forLocale(Locale.getDefault());
-
- return new MonthTitleSetter(activity, monthLabels);
- }
-
- MonthTitleSetter(Activity activity, MonthLabels monthLabels) {
- this.activity = activity;
- this.monthLabels = monthLabels;
- }
-
-
- void updateWithMonth(int monthToDisplay) {
- String monthLabel = monthLabels.getMonthOfYear(monthToDisplay);
- activity.setTitle(monthLabel);
- }
-
-}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/SearchTransitioner.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/SearchTransitioner.java
new file mode 100644
index 00000000..068465f5
--- /dev/null
+++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/SearchTransitioner.java
@@ -0,0 +1,102 @@
+package com.alexstyl.specialdates.upcoming;
+
+import android.app.Activity;
+import android.support.transition.Fade;
+import android.support.transition.Transition;
+import android.support.transition.TransitionManager;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import com.alexstyl.specialdates.Navigator;
+import com.alexstyl.specialdates.R;
+import com.alexstyl.specialdates.transition.FadeInTransition;
+import com.alexstyl.specialdates.transition.FadeOutTransition;
+import com.alexstyl.specialdates.transition.SimpleTransitionListener;
+import com.alexstyl.specialdates.ui.ViewFader;
+import com.alexstyl.specialdates.util.Utils;
+
+import static android.view.View.GONE;
+import static android.view.View.VISIBLE;
+
+public final class SearchTransitioner {
+
+ private final Activity activity;
+ private final Navigator navigator;
+ private final ViewGroup activityContent;
+ private final ExposedSearchToolbar toolbar;
+ private final ViewFader viewFader;
+
+ private final int toolbarMargin;
+ private boolean transitioning;
+
+ public SearchTransitioner(Activity activity,
+ Navigator navigator,
+ ViewGroup activityContent,
+ ExposedSearchToolbar toolbar,
+ ViewFader viewFader) {
+ this.activity = activity;
+ this.navigator = navigator;
+ this.activityContent = activityContent;
+ this.toolbar = toolbar;
+ this.viewFader = viewFader;
+ this.toolbarMargin = activity.getResources().getDimensionPixelSize(R.dimen.padding_tight);
+ }
+
+ public void transitionToSearch() {
+ if (transitioning) {
+ return;
+ }
+ if (supportsTransitions()) {
+
+ Transition transition = FadeOutTransition.withAction(navigateToSearchWhenDone());
+ TransitionManager.beginDelayedTransition(toolbar, transition);
+ expandToolbar();
+ viewFader.hideContentOf(toolbar);
+
+ TransitionManager.beginDelayedTransition(activityContent, new Fade(Fade.OUT));
+ activityContent.setVisibility(GONE);
+ } else {
+ navigator.toSearch();
+ }
+ }
+
+ private void expandToolbar() {
+ FrameLayout.LayoutParams frameLP = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
+ frameLP.setMargins(0, 0, 0, 0);
+ toolbar.setLayoutParams(frameLP);
+ }
+
+ private Transition.TransitionListener navigateToSearchWhenDone() {
+ return new SimpleTransitionListener() {
+
+ @Override
+ public void onTransitionStart(Transition transition) {
+ transitioning = true;
+ }
+
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ transitioning = false;
+ navigator.toSearch();
+ activity.overridePendingTransition(0, 0);
+ }
+ };
+ }
+
+ private static boolean supportsTransitions() {
+ return Utils.hasKitKat();
+ }
+
+ public void onActivityResumed() {
+ if (supportsTransitions()) {
+ TransitionManager.beginDelayedTransition(toolbar, FadeInTransition.createTransition());
+ FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) toolbar.getLayoutParams();
+ layoutParams.setMargins(toolbarMargin, toolbarMargin, toolbarMargin, toolbarMargin);
+ viewFader.showContent(toolbar);
+ toolbar.setLayoutParams(layoutParams);
+
+ TransitionManager.beginDelayedTransition(activityContent, new Fade(Fade.IN));
+ activityContent.setVisibility(VISIBLE);
+ }
+ }
+}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFragment.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFragment.java
index 9ddbd96d..42a7b093 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFragment.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/UpcomingEventsFragment.java
@@ -13,8 +13,8 @@
import com.alexstyl.specialdates.R;
import com.alexstyl.specialdates.analytics.Action;
-import com.alexstyl.specialdates.analytics.Analytics;
import com.alexstyl.specialdates.analytics.ActionWithParameters;
+import com.alexstyl.specialdates.analytics.Analytics;
import com.alexstyl.specialdates.analytics.Firebase;
import com.alexstyl.specialdates.analytics.Screen;
import com.alexstyl.specialdates.date.CelebrationDate;
@@ -22,8 +22,8 @@
import com.alexstyl.specialdates.date.DayDate;
import com.alexstyl.specialdates.datedetails.DateDetailsActivity;
import com.alexstyl.specialdates.search.SearchActivity;
-import com.alexstyl.specialdates.theming.Themer;
import com.alexstyl.specialdates.ui.base.MementoFragment;
+import com.alexstyl.specialdates.upcoming.ui.OnUpcomingEventClickedListener;
import com.alexstyl.specialdates.upcoming.ui.UpcomingEventsListView;
import com.alexstyl.specialdates.views.FabPaddingSetter;
import com.novoda.notils.caster.Views;
@@ -38,22 +38,18 @@ public class UpcomingEventsFragment extends MementoFragment {
private ProgressBar progressBar;
private TextView emptyView;
private SettingsMonitor monitor;
- private MonthTitleSetter titleSetter;
private UpcomingEventsProvider upcomingEventsProvider;
private boolean mustScrollToPosition = true;
private GoToTodayEnabler goToTodayEnabler;
- private Themer themer;
private Analytics firebase;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
- themer = Themer.get();
firebase = Firebase.get(getActivity());
monitor = SettingsMonitor.newInstance(getActivity());
monitor.initialise();
- titleSetter = MonthTitleSetter.createSetterFor(getActivity());
goToTodayEnabler = new GoToTodayEnabler(getMementoActivity());
upcomingEventsProvider = UpcomingEventsProvider.newInstance(getActivity(), onEventsLoadedListener);
}
@@ -61,28 +57,16 @@ public void onCreate(Bundle savedInstanceState) {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
- if (isUsingDarkIcons()) {
- inflater.inflate(R.menu.menu_upcoming_dark, menu);
- } else {
- inflater.inflate(R.menu.menu_upcoming_light, menu);
- }
+ inflater.inflate(R.menu.menu_upcoming_dark, menu);
goToTodayEnabler.reattachTo(menu);
}
- private boolean isUsingDarkIcons() {
- return themer.isActivityUsingDarkIcons(getActivity());
- }
-
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_today:
onGoToTodayRequested();
return true;
- case R.id.action_search: {
- onSearchRequested();
- return true;
- }
default:
break;
}
@@ -106,6 +90,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
new FabPaddingSetter().setBottomPaddingTo(upcomingEventsListView);
+ upcomingEventsListView.setHasFixedSize(true);
}
@Override
@@ -155,8 +140,7 @@ private void showLoading() {
emptyView.setVisibility(View.GONE);
}
- private final UpcomingEventsListView.Listener listClickListener = new UpcomingEventsListView.Listener() {
-
+ private final OnUpcomingEventClickedListener listClickListener = new OnUpcomingEventClickedListener() {
@Override
public void onContactEventPressed(View view, ContactEvent contact) {
firebase.trackAction(action);
@@ -169,11 +153,6 @@ public void onCardPressed(DayDate date) {
Intent intent = DateDetailsActivity.getStartIntent(getActivity(), date.getDayOfMonth(), date.getMonth(), date.getYear());
startActivity(intent);
}
-
- @Override
- public void onDifferentMonthScrolled(int month) {
- titleSetter.updateWithMonth(month);
- }
};
public boolean onSearchRequested() {
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsAdapter.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsAdapter.java
index 2d17fb2d..98dab06e 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsAdapter.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsAdapter.java
@@ -118,7 +118,7 @@ public int getMonthAt(int position) {
return integer == null ? -1 : integer;
}
- public void setUpcomingEvents(List upcomingEvents, UpcomingEventsListView.Listener listener) {
+ public void setUpcomingEvents(List upcomingEvents, OnUpcomingEventClickedListener listener) {
this.listener = listener;
if (this.celebrationDates == upcomingEvents) {
return;
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsListView.java b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsListView.java
index 604847b3..7dc5b3ac 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsListView.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/upcoming/ui/UpcomingEventsListView.java
@@ -11,7 +11,6 @@
import com.alexstyl.specialdates.images.ImageLoader;
import com.alexstyl.specialdates.images.PauseImageLoadingScrollListener;
import com.alexstyl.specialdates.ui.widget.ScrollingLinearLayoutManager;
-import com.alexstyl.specialdates.upcoming.MonthSectionScrollListener;
import java.util.List;
@@ -20,12 +19,9 @@ public class UpcomingEventsListView extends RecyclerView {
private UpcomingEventsAdapter adapter;
private ScrollingLinearLayoutManager layoutManager;
- private Listener listener;
-
public UpcomingEventsListView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
- setHasFixedSize(true);
layoutManager = new ScrollingLinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false, 600);
setLayoutManager(layoutManager);
@@ -39,19 +35,10 @@ public UpcomingEventsListView(Context context, @Nullable AttributeSet attrs) {
setAdapter(adapter);
addOnScrollListener(PauseImageLoadingScrollListener.newInstance(imageLoader));
-
- final MonthSectionScrollListener monthSectionScrollListener = new MonthSectionScrollListener(adapter, layoutManager) {
- @Override
- protected void onDifferentMonthScrolled(int month) {
- listener.onDifferentMonthScrolled(month);
- }
- };
- addOnScrollListener(monthSectionScrollListener);
}
- public void updateWith(List dates, Listener listener) {
- this.listener = listener;
- this.adapter.setUpcomingEvents(dates, listener);
+ public void updateWith(List dates, OnUpcomingEventClickedListener listener) {
+ adapter.setUpcomingEvents(dates, listener);
}
public void scrollToToday(final boolean smoothScroll) {
@@ -120,7 +107,4 @@ public boolean isDisplayingEvents() {
return adapter.getItemCount() > 0;
}
- public interface Listener extends OnUpcomingEventClickedListener {
- void onDifferentMonthScrolled(int month);
- }
}
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/util/Notifier.java b/mobile/src/main/java/com/alexstyl/specialdates/util/Notifier.java
index 782193d9..bb277cf7 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/util/Notifier.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/util/Notifier.java
@@ -197,7 +197,7 @@ private boolean supportsPublicNotifications() {
}
private boolean shouldDisplayContactImage(int contactCount) {
- return Utils.hasHoneycomb() && contactCount == 1;
+ return contactCount == 1;
}
public void forNamedays(List names, Date date) {
diff --git a/mobile/src/main/java/com/alexstyl/specialdates/util/Utils.java b/mobile/src/main/java/com/alexstyl/specialdates/util/Utils.java
index 45d68b8b..02be5b06 100644
--- a/mobile/src/main/java/com/alexstyl/specialdates/util/Utils.java
+++ b/mobile/src/main/java/com/alexstyl/specialdates/util/Utils.java
@@ -16,15 +16,10 @@
package com.alexstyl.specialdates.util;
-import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Vibrator;
@@ -34,17 +29,14 @@
import android.view.View;
import android.widget.Toast;
-import com.alexstyl.specialdates.BuildConfig;
import com.alexstyl.specialdates.ErrorTracker;
import com.alexstyl.specialdates.MementoApplication;
-import com.alexstyl.specialdates.PayPal;
import com.alexstyl.specialdates.R;
import com.alexstyl.specialdates.contact.actions.IntentAction;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
@@ -58,22 +50,6 @@ public class Utils {
private Utils() {
}
- /**
- * Uses static final constants to detect if the device's platform version is
- * Honeycomb or later.
- */
- public static boolean hasHoneycomb() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
- }
-
- /**
- * Uses static final constants to detect if the device's platform version is
- * ICS or later.
- */
- public static boolean hasICS() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
- }
-
public static boolean hasJellyBean() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}
@@ -97,10 +73,6 @@ public static boolean hasKitKat() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
}
- public static boolean isRunningKitKat() {
- return Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT;
- }
-
/**
* Uses static final constants to detect if the device's platform version is
* Lollipop or later.
@@ -164,52 +136,11 @@ public static String getAndroidVersion() {
return android.os.Build.VERSION.RELEASE;
}
- /**
- * Returns whether the device has
- *
- * @param context The context to use
- * @return
- */
- @SuppressLint("NewApi")
public static boolean hasVibrator(Context context) {
Vibrator vibr = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
- if (!hasHoneycomb()) {
- return vibr != null;
- }
return vibr.hasVibrator();
}
- /**
- * Checks if the device is currently connected to the webz!
- *
- * @param context The context to use
- * @return Whether the device is online or not... duh
- */
- public static boolean isOnline(Context context) {
- ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo ni = cm.getActiveNetworkInfo();
- if (ni == null) {
- // There are no active networks.
- return false;
- }
- return ni.isConnectedOrConnecting();
- }
-
- /**
- * Returns the height of the navigation bars height
- *
- * @param context
- * @return
- */
- final public static int getNavigationBarHeight(Context context) {
- Resources resources = context.getResources();
- int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
- if (resourceId > 0) {
- return resources.getDimensionPixelSize(resourceId);
- }
- return 0;
- }
-
/**
* Starts a {@link IntentAction}. A Toast is displayed if the action throws an ActivityNotFoundException
*
@@ -251,27 +182,11 @@ public String getName() {
);
}
- /**
- * Checks if the running device has any installed applications that can handle the given intent
- *
- * @param context
- * @param intent
- * @return
- */
- public static boolean isCallable(Context context, Intent intent) {
- List list = context.getPackageManager().queryIntentActivities(
- intent,
- PackageManager.MATCH_DEFAULT_ONLY
- );
- return list.size() > 0;
- }
-
/**
* Returns a JSON value from the raw folder, of the given resID
*
* @param context The context to use
* @param resID The resource ID of the JSON file
- * @return
* @throws android.content.res.Resources.NotFoundException if the resource is not a JSON
*/
public static JSONObject getJSON(@NonNull Context context, @RawRes int resID) {
@@ -296,36 +211,4 @@ public static JSONObject getJSON(@NonNull Context context, @RawRes int resID) {
}
}
- /**
- * Compares whether one is equal with at least one of the others
- *
- * @param one
- * @param others
- * @return
- */
- public static boolean equalsTo(Object one, Object... others) {
- for (Object other : others) {
- if (one.equals(other)) {
- return true;
- }
- }
- return false;
- }
-
- public static boolean openPayPalDonation(Context context) {
- try {
- Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setData(Uri.parse(PayPal.URL_DONATIONS));
- context.startActivity(intent);
- return true;
- } catch (ActivityNotFoundException e) {
- if (BuildConfig.DEBUG) {
- // do nothing if we there is no browser installed
- Toast.makeText(context, "Exception thrown!", Toast.LENGTH_SHORT).show();
- e.printStackTrace();
- }
- }
- return false;
- }
-
}
diff --git a/mobile/src/main/res/drawable-hdpi/ic_action_arrow_dark_back.png b/mobile/src/main/res/drawable-hdpi/ic_action_left_semitransparent.png
similarity index 100%
rename from mobile/src/main/res/drawable-hdpi/ic_action_arrow_dark_back.png
rename to mobile/src/main/res/drawable-hdpi/ic_action_left_semitransparent.png
diff --git a/mobile/src/main/res/drawable-hdpi/ic_action_navigation_arrow_back.png b/mobile/src/main/res/drawable-hdpi/ic_action_navigation_arrow_back.png
new file mode 100755
index 00000000..a9df1796
Binary files /dev/null and b/mobile/src/main/res/drawable-hdpi/ic_action_navigation_arrow_back.png differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_action_search.png b/mobile/src/main/res/drawable-hdpi/ic_action_search.png
old mode 100644
new mode 100755
index 857135d2..9810302b
Binary files a/mobile/src/main/res/drawable-hdpi/ic_action_search.png and b/mobile/src/main/res/drawable-hdpi/ic_action_search.png differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_action_today.png b/mobile/src/main/res/drawable-hdpi/ic_action_today.png
old mode 100644
new mode 100755
index fe825d98..eaf359f4
Binary files a/mobile/src/main/res/drawable-hdpi/ic_action_today.png and b/mobile/src/main/res/drawable-hdpi/ic_action_today.png differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png b/mobile/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png
deleted file mode 100644
index 52565d09..00000000
Binary files a/mobile/src/main/res/drawable-hdpi/ic_exit_to_app_white_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_search_black_24dp.png b/mobile/src/main/res/drawable-hdpi/ic_search_black_24dp.png
deleted file mode 100644
index c593e7ad..00000000
Binary files a/mobile/src/main/res/drawable-hdpi/ic_search_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-hdpi/ic_today_black_24dp.png b/mobile/src/main/res/drawable-hdpi/ic_today_black_24dp.png
deleted file mode 100644
index 03680a76..00000000
Binary files a/mobile/src/main/res/drawable-hdpi/ic_today_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_action_arrow_dark_back.png b/mobile/src/main/res/drawable-mdpi/ic_action_left_semitransparent.png
similarity index 100%
rename from mobile/src/main/res/drawable-mdpi/ic_action_arrow_dark_back.png
rename to mobile/src/main/res/drawable-mdpi/ic_action_left_semitransparent.png
diff --git a/mobile/src/main/res/drawable-mdpi/ic_action_navigation_arrow_back.png b/mobile/src/main/res/drawable-mdpi/ic_action_navigation_arrow_back.png
new file mode 100755
index 00000000..6ae1c1d0
Binary files /dev/null and b/mobile/src/main/res/drawable-mdpi/ic_action_navigation_arrow_back.png differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_action_search.png b/mobile/src/main/res/drawable-mdpi/ic_action_search.png
old mode 100644
new mode 100755
index 8d57e2ba..f70bef02
Binary files a/mobile/src/main/res/drawable-mdpi/ic_action_search.png and b/mobile/src/main/res/drawable-mdpi/ic_action_search.png differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_action_today.png b/mobile/src/main/res/drawable-mdpi/ic_action_today.png
old mode 100644
new mode 100755
index 82a86d8d..c7c57fd2
Binary files a/mobile/src/main/res/drawable-mdpi/ic_action_today.png and b/mobile/src/main/res/drawable-mdpi/ic_action_today.png differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png b/mobile/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png
deleted file mode 100644
index 461be00a..00000000
Binary files a/mobile/src/main/res/drawable-mdpi/ic_exit_to_app_white_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_search_black_24dp.png b/mobile/src/main/res/drawable-mdpi/ic_search_black_24dp.png
deleted file mode 100644
index 6b163432..00000000
Binary files a/mobile/src/main/res/drawable-mdpi/ic_search_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-mdpi/ic_today_black_24dp.png b/mobile/src/main/res/drawable-mdpi/ic_today_black_24dp.png
deleted file mode 100644
index 227bfca9..00000000
Binary files a/mobile/src/main/res/drawable-mdpi/ic_today_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_action_arrow_dark_back.png b/mobile/src/main/res/drawable-xhdpi/ic_action_left_semitransparent.png
similarity index 100%
rename from mobile/src/main/res/drawable-xhdpi/ic_action_arrow_dark_back.png
rename to mobile/src/main/res/drawable-xhdpi/ic_action_left_semitransparent.png
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_action_navigation_arrow_back.png b/mobile/src/main/res/drawable-xhdpi/ic_action_navigation_arrow_back.png
new file mode 100755
index 00000000..39dde07a
Binary files /dev/null and b/mobile/src/main/res/drawable-xhdpi/ic_action_navigation_arrow_back.png differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_action_search.png b/mobile/src/main/res/drawable-xhdpi/ic_action_search.png
old mode 100644
new mode 100755
index d9fb6338..ccdfb3fd
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_action_search.png and b/mobile/src/main/res/drawable-xhdpi/ic_action_search.png differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_action_today.png b/mobile/src/main/res/drawable-xhdpi/ic_action_today.png
old mode 100644
new mode 100755
index 4fe7595f..80b49c4b
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_action_today.png and b/mobile/src/main/res/drawable-xhdpi/ic_action_today.png differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png b/mobile/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png
deleted file mode 100644
index 07847bd2..00000000
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_exit_to_app_white_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_search_black_24dp.png b/mobile/src/main/res/drawable-xhdpi/ic_search_black_24dp.png
deleted file mode 100644
index 63819026..00000000
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_search_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xhdpi/ic_today_black_24dp.png b/mobile/src/main/res/drawable-xhdpi/ic_today_black_24dp.png
deleted file mode 100644
index 2d6a849c..00000000
Binary files a/mobile/src/main/res/drawable-xhdpi/ic_today_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_action_arrow_dark_back.png b/mobile/src/main/res/drawable-xxhdpi/ic_action_left_semitransparent.png
similarity index 100%
rename from mobile/src/main/res/drawable-xxhdpi/ic_action_arrow_dark_back.png
rename to mobile/src/main/res/drawable-xxhdpi/ic_action_left_semitransparent.png
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_action_navigation_arrow_back.png b/mobile/src/main/res/drawable-xxhdpi/ic_action_navigation_arrow_back.png
new file mode 100755
index 00000000..e5287823
Binary files /dev/null and b/mobile/src/main/res/drawable-xxhdpi/ic_action_navigation_arrow_back.png differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_action_search.png b/mobile/src/main/res/drawable-xxhdpi/ic_action_search.png
old mode 100644
new mode 100755
index b1048235..4a85a4cd
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_action_search.png and b/mobile/src/main/res/drawable-xxhdpi/ic_action_search.png differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_action_today.png b/mobile/src/main/res/drawable-xxhdpi/ic_action_today.png
old mode 100644
new mode 100755
index ad33347b..d5b29841
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_action_today.png and b/mobile/src/main/res/drawable-xxhdpi/ic_action_today.png differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png b/mobile/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png
deleted file mode 100644
index c04fe6e0..00000000
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_exit_to_app_white_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png b/mobile/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png
deleted file mode 100644
index 3ae490ef..00000000
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_search_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxhdpi/ic_today_black_24dp.png b/mobile/src/main/res/drawable-xxhdpi/ic_today_black_24dp.png
deleted file mode 100644
index 229f0445..00000000
Binary files a/mobile/src/main/res/drawable-xxhdpi/ic_today_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_action_navigation_arrow_back.png b/mobile/src/main/res/drawable-xxxhdpi/ic_action_navigation_arrow_back.png
new file mode 100755
index 00000000..71d044e5
Binary files /dev/null and b/mobile/src/main/res/drawable-xxxhdpi/ic_action_navigation_arrow_back.png differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_action_search.png b/mobile/src/main/res/drawable-xxxhdpi/ic_action_search.png
new file mode 100755
index 00000000..2653c039
Binary files /dev/null and b/mobile/src/main/res/drawable-xxxhdpi/ic_action_search.png differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_action_today.png b/mobile/src/main/res/drawable-xxxhdpi/ic_action_today.png
new file mode 100755
index 00000000..e9d5192c
Binary files /dev/null and b/mobile/src/main/res/drawable-xxxhdpi/ic_action_today.png differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png b/mobile/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png
deleted file mode 100644
index 27a9d7b0..00000000
Binary files a/mobile/src/main/res/drawable-xxxhdpi/ic_exit_to_app_white_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png b/mobile/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png
deleted file mode 100644
index 21be5729..00000000
Binary files a/mobile/src/main/res/drawable-xxxhdpi/ic_search_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable-xxxhdpi/ic_today_black_24dp.png b/mobile/src/main/res/drawable-xxxhdpi/ic_today_black_24dp.png
deleted file mode 100644
index 38704111..00000000
Binary files a/mobile/src/main/res/drawable-xxxhdpi/ic_today_black_24dp.png and /dev/null differ
diff --git a/mobile/src/main/res/drawable/card_noshadow.xml b/mobile/src/main/res/drawable/card_noshadow.xml
new file mode 100644
index 00000000..48d13eb2
--- /dev/null
+++ b/mobile/src/main/res/drawable/card_noshadow.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/mobile/src/main/res/layout/activity_main.xml b/mobile/src/main/res/layout/activity_main.xml
index 7b64d35c..db83d92b 100644
--- a/mobile/src/main/res/layout/activity_main.xml
+++ b/mobile/src/main/res/layout/activity_main.xml
@@ -2,19 +2,30 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_horizontal">
+ android:layout_height="match_parent">
-
+ android:layout_height="@dimen/toolbar_semi_expanded_height"
+ android:background="?attr/colorPrimary"
+ android:elevation="@dimen/toolbar_elevation">
+
+
+
+
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/src/main/res/layout/fragment_contact_details.xml b/mobile/src/main/res/layout/fragment_contact_details.xml
deleted file mode 100644
index 8df1ce95..00000000
--- a/mobile/src/main/res/layout/fragment_contact_details.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mobile/src/main/res/layout/fragment_search.xml b/mobile/src/main/res/layout/fragment_search.xml
deleted file mode 100644
index 0a562370..00000000
--- a/mobile/src/main/res/layout/fragment_search.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/mobile/src/main/res/layout/merge_searchbar.xml b/mobile/src/main/res/layout/merge_searchbar.xml
new file mode 100644
index 00000000..0fb1dc59
--- /dev/null
+++ b/mobile/src/main/res/layout/merge_searchbar.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
diff --git a/mobile/src/main/res/layout/searchbar.xml b/mobile/src/main/res/layout/searchbar.xml
deleted file mode 100644
index 372ce657..00000000
--- a/mobile/src/main/res/layout/searchbar.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mobile/src/main/res/layout/toolbar_search.xml b/mobile/src/main/res/layout/toolbar_search.xml
new file mode 100644
index 00000000..5aac703e
--- /dev/null
+++ b/mobile/src/main/res/layout/toolbar_search.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/mobile/src/main/res/menu/menu_search.xml b/mobile/src/main/res/menu/menu_search.xml
new file mode 100644
index 00000000..02e644b3
--- /dev/null
+++ b/mobile/src/main/res/menu/menu_search.xml
@@ -0,0 +1,11 @@
+
+
diff --git a/mobile/src/main/res/menu/menu_upcoming_dark.xml b/mobile/src/main/res/menu/menu_upcoming_dark.xml
index de8c7968..01d4cedd 100644
--- a/mobile/src/main/res/menu/menu_upcoming_dark.xml
+++ b/mobile/src/main/res/menu/menu_upcoming_dark.xml
@@ -4,16 +4,9 @@
-
-
diff --git a/mobile/src/main/res/transition/changebounds.xml b/mobile/src/main/res/transition/changebounds.xml
new file mode 100644
index 00000000..eeaa7e8b
--- /dev/null
+++ b/mobile/src/main/res/transition/changebounds.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/mobile/src/main/res/transition/explode.xml b/mobile/src/main/res/transition/explode.xml
new file mode 100644
index 00000000..3b00a31c
--- /dev/null
+++ b/mobile/src/main/res/transition/explode.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/mobile/src/main/res/transition/fade_and_changebounds.xml b/mobile/src/main/res/transition/fade_and_changebounds.xml
new file mode 100644
index 00000000..8a427181
--- /dev/null
+++ b/mobile/src/main/res/transition/fade_and_changebounds.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/mobile/src/main/res/values-v21/search-resources.xml b/mobile/src/main/res/values-v21/search-resources.xml
new file mode 100644
index 00000000..feb2cd46
--- /dev/null
+++ b/mobile/src/main/res/values-v21/search-resources.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
diff --git a/mobile/src/main/res/values/search-resources.xml b/mobile/src/main/res/values/search-resources.xml
new file mode 100644
index 00000000..f1ea3d11
--- /dev/null
+++ b/mobile/src/main/res/values/search-resources.xml
@@ -0,0 +1,9 @@
+
+
+ @string/Search_for_contacts
+ @string/Search_for_contacts_or_namedays
+ @string/Clear
+ #808080
+
+
+
diff --git a/mobile/src/main/res/values/string.xml b/mobile/src/main/res/values/string.xml
new file mode 100644
index 00000000..5333ef9b
--- /dev/null
+++ b/mobile/src/main/res/values/string.xml
@@ -0,0 +1,4 @@
+
+
+ Clear
+
diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml
index 50e5203d..c5abb223 100644
--- a/mobile/src/main/res/values/strings.xml
+++ b/mobile/src/main/res/values/strings.xml
@@ -1,64 +1,65 @@
-
- Memento Namedays
- Today
- Tomorrow
- Birthday
- Birthdays
- Name Days
- Name Day
- "It's %s's birthday!"
- "It's %s's nameday!"
- No name days for this day
- No contact has their birthday this day
- Settings
- Disable
- Enable
- %1$s
- %1$s and %2$s
- %1$s and %2$d others
- About
- Daily Reminder Service
- Display Name Days
- Name Days will be displayed for all of your contacts
- Name Days will not be displayed
- Contact the developer
- Found a bug? Have a suggestion? Let me know!
- Choose
- number
- Nameday on %s
- Birthday on %s
- Turns %1$d on %2$s
- Call
- Send SMS
- Send e-mail
- No application found in order to perform this action
- Send e-mail via
- Daily Reminder
- "Remind me for every day's events"
- Ringtone
- Vibrate
- Every day at %s
- Set time
- Set
- Discard
- Contact added
- Contact could not be added
- Contact updated
- Contact could not be updated
- @string/upcoming
- Silent
- Contacts celebrating this day
- There are no contacts celebrating this day
- Upcoming
- Turns %1$d
- Today\'s Namedays
- Check out %1$s - a sweet looking birthdays and namedays reminder app for Android! Get it at %2$s
- Share via
- Licences
- Developed and designed by Alex Styl
+
+ Memento Namedays
+ Today
+ Tomorrow
+ Birthday
+ Birthdays
+ Name Days
+ Name Day
+ "It's %s's birthday!"
+ "It's %s's nameday!"
+ No name days for this day
+ No contact has their birthday this day
+ Settings
+ Disable
+ Enable
+ %1$s
+ %1$s and %2$s
+ %1$s and %2$d others
+ About
+ Daily Reminder Service
+ Display Name Days
+ Name Days will be displayed for all of your contacts
+ Name Days will not be displayed
+ Contact the developer
+ Found a bug? Have a suggestion? Let me know!
+ Choose
+ number
+ Nameday on %s
+ Birthday on %s
+ Turns %1$d on %2$s
+ Call
+ Send SMS
+ Send e-mail
+ No application found in order to perform this action
+ Send e-mail via
+ Daily Reminder
+ "Remind me for every day's events"
+ Ringtone
+ Vibrate
+ Every day at %s
+ Set time
+ Set
+ Discard
+ Contact added
+ Contact could not be added
+ Contact updated
+ Contact could not be updated
+ @string/upcoming
+ Silent
+ Contacts celebrating this day
+ There are no contacts celebrating this day
+ Upcoming
+ Turns %1$d
+ Today\'s Namedays
+ Check out %1$s - a sweet looking birthdays and namedays reminder app for Android! Get it at %2$s
+ Share via
+ Licences
+ Developed and designed by Alex Styl
"Special thanks to
Andreas Sfakianakis for his work on the Greeklish library
@@ -66,94 +67,96 @@
Aggela Stylianidou for the French translation
Gian Maria Calzolari for the Italian translation
Andrejs Kotovs for the Latvian translation"
- and *%s* for using and supporting the app! :)
- Something is wrong with the app? Got a suggestion? Send an email at %s
- You
- On
- Off
- Thank you for supporting the app
- Donate
- Loading…
- Search
- Contacts
- Nameday on
- Show more
- Create
-
- (No name)
- Include year?
- Save
- Add
- No birthday set
- No nameday for the name %s
- Edit
- Add birthday
- Search
- and
- Greek
- Czech
- Slovak
- Russian
- Latvian
- Hungarian
- Nameday Calendar
- Silent
- "Memento - Namedays"
- Share
- Support the app
- Open Facebook Page
- How would you rate the app?
- "It\'s pretty much horrible"
- "I don't like it"
- "It's okay"
- "It's good"
- "I LOVE it!"
- Rate
- Message
- %1$s turns %2$d
- No results found
- %d contacts celebrate today
- Today\'s Namedays
- "Today's nameday"
- "Today's namedays"
- %s via…
- Like Page
- Rate the app
- Like Facebook Page
- Namedays for %1$s
- Get %1$s at %2$s
- You can hide names you don\'t want to appear in the app, by long pressing on them.
- OK, got it
- Namedays will be displayed for stored contacts only
- Namedays will be displays for the namedays of all year
- Namedays for Contacts only
- I hope you enjoy using the app, and it is useful for you. Here are some ways you can support the app:
- Translate the app
- Translating the app
- Visit the following url from your computer browser
-
- Copy Link
- Link copied to clipboard
- Select the amount you would like to donate
- Open Wall
- View contact
- No birthday set
- "No contacts with special events found.\nTap the '+' to add some"
- "No contacts with special events found"
- Add birthday
- Birthday date
- Contact name
- Themes
- Romanian
- Configure Widget
- Done
- Transparency
- Dark theme?
- Contact Names
- Bank holiday
- Bank holidays
- Google+ community
- Display Bankholidays
- Bankholidays Country
- Bankholidays are currently supported only for Greek
+ and *%s* for using and supporting the app! :)
+ Something is wrong with the app? Got a suggestion? Send an email at %s
+ You
+ On
+ Off
+ Thank you for supporting the app
+ Donate
+ Loading…
+ Search
+ Contacts
+ Nameday on
+ Show more
+ Create
+
+ (No name)
+ Include year?
+ Save
+ Add
+ No birthday set
+ No nameday for the name %s
+ Edit
+ Add birthday
+ Search
+ and
+ Greek
+ Czech
+ Slovak
+ Russian
+ Latvian
+ Hungarian
+ Nameday Calendar
+ Silent
+ "Memento - Namedays"
+ Share
+ Support the app
+ Open Facebook Page
+ How would you rate the app?
+ "It\'s pretty much horrible"
+ "I don't like it"
+ "It's okay"
+ "It's good"
+ "I LOVE it!"
+ Rate
+ Message
+ %1$s turns %2$d
+ No results found
+ %d contacts celebrate today
+ Today\'s Namedays
+ "Today's nameday"
+ "Today's namedays"
+ %s via…
+ Like Page
+ Rate the app
+ Like Facebook Page
+ Namedays for %1$s
+ Get %1$s at %2$s
+ You can hide names you don\'t want to appear in the app, by long pressing on them.
+ OK, got it
+ Namedays will be displayed for stored contacts only
+ Namedays will be displays for the namedays of all year
+ Namedays for Contacts only
+ I hope you enjoy using the app, and it is useful for you. Here are some ways you can support the app:
+ Translate the app
+ Translating the app
+ Visit the following url from your computer browser
+
+ Copy Link
+ Link copied to clipboard
+ Select the amount you would like to donate
+ Open Wall
+ View contact
+ No birthday set
+ "No contacts with special events found.\nTap the '+' to add some"
+ "No contacts with special events found"
+ Add birthday
+ Birthday date
+ Contact name
+ Themes
+ Romanian
+ Configure Widget
+ Done
+ Transparency
+ Dark theme?
+ Contact Names
+ Bank holiday
+ Bank holidays
+ Google+ community
+ Display Bankholidays
+ Bankholidays Country
+ Bankholidays are currently supported only for Greek
+ Search for contacts
+ Search for contacts or namedays
diff --git a/mobile/src/main/res/values/toolbar-resources.xml b/mobile/src/main/res/values/toolbar-resources.xml
index b12f1776..250e5b71 100644
--- a/mobile/src/main/res/values/toolbar-resources.xml
+++ b/mobile/src/main/res/values/toolbar-resources.xml
@@ -2,4 +2,7 @@
4dp
56dp
+ 64dp
+
+
diff --git a/mobile/src/main/res/values/upcoming-resources.xml b/mobile/src/main/res/values/upcoming-resources.xml
index 694a11d4..fdb6a65e 100644
--- a/mobile/src/main/res/values/upcoming-resources.xml
+++ b/mobile/src/main/res/values/upcoming-resources.xml
@@ -16,6 +16,15 @@
+
+
+
+