() {
+ @Override
+ protected Random initialValue() {
+ return new Random();
+ }
+ }.get();
+ }
+ }
+}
diff --git a/app/src/main/java/com/tenor/android/sdk/util/SdkListUtils.java b/app/src/main/java/com/tenor/android/sdk/util/SdkListUtils.java
new file mode 100644
index 0000000..7654d1f
--- /dev/null
+++ b/app/src/main/java/com/tenor/android/sdk/util/SdkListUtils.java
@@ -0,0 +1,35 @@
+package com.tenor.android.sdk.util;
+
+import android.support.annotation.NonNull;
+
+import com.tenor.android.core.util.AbstractListUtils;
+
+import java.util.Random;
+
+public class SdkListUtils extends AbstractListUtils {
+
+ /**
+ * Shuffle a given {@link int}[]
+ *
+ * A implementation of Fisher–Yates shuffle
+ *
+ * @param array given {@link int}[] to be shuffled
+ * @return a shuffled {@link int}[]
+ */
+ @NonNull
+ public static int[] shuffle(@NonNull int[] array) {
+ if (array.length <= 0) {
+ return array;
+ }
+ Random random = RandomCompat.get();
+ int randInt;
+ int temp;
+ for (int i = array.length - 1; i > 0; i--) {
+ randInt = random.nextInt(i + 1);
+ temp = array[randInt];
+ array[randInt] = array[i];
+ array[i] = temp;
+ }
+ return array;
+ }
+}
diff --git a/app/src/main/java/com/tenor/android/sdk/view/ISearchSuggestionView.java b/app/src/main/java/com/tenor/android/sdk/view/ISearchSuggestionView.java
new file mode 100644
index 0000000..e2d7b7a
--- /dev/null
+++ b/app/src/main/java/com/tenor/android/sdk/view/ISearchSuggestionView.java
@@ -0,0 +1,16 @@
+package com.tenor.android.sdk.view;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.tenor.android.core.view.IBaseView;
+
+import java.util.List;
+
+public interface ISearchSuggestionView extends IBaseView {
+
+ void onReceiveSearchSuggestionsSucceeded(@NonNull String query, @NonNull List suggestions);
+
+ void onReceiveSearchSuggestionsFailed(@NonNull String query, @Nullable Exception error);
+}
+
diff --git a/app/src/main/java/com/tenor/android/sdk/widget/SearchSuggestionRecyclerView.java b/app/src/main/java/com/tenor/android/sdk/widget/SearchSuggestionRecyclerView.java
new file mode 100644
index 0000000..2d427cc
--- /dev/null
+++ b/app/src/main/java/com/tenor/android/sdk/widget/SearchSuggestionRecyclerView.java
@@ -0,0 +1,186 @@
+package com.tenor.android.sdk.widget;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.annotation.CallSuper;
+import android.support.annotation.IntRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.StaggeredGridLayoutManager;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.tenor.android.core.response.impl.SearchSuggestionResponse;
+import com.tenor.android.core.util.AbstractListUtils;
+import com.tenor.android.core.util.AbstractUIUtils;
+import com.tenor.android.core.util.AbstractWeakReferenceUtils;
+import com.tenor.android.core.weakref.IWeakRefObject;
+import com.tenor.android.sdk.adapter.SearchSuggestionAdapter;
+import com.tenor.android.sdk.holder.SearchSuggestionVH;
+import com.tenor.android.sdk.presenter.impl.SearchSuggestionPresenter;
+import com.tenor.android.sdk.rvitem.SearchSuggestionRVItem;
+import com.tenor.android.sdk.util.ColorPalette;
+import com.tenor.android.sdk.view.ISearchSuggestionView;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import retrofit2.Call;
+
+/**
+ * {@link SearchSuggestionRecyclerView} is a subclass of {@link RecyclerView} for search suggestions
+ *
+ * "AppCompatTextView" under "com.android.support:appcompat-v7" is not required, yet highly recommended
+ * to ensure this widget is working properly on API 20-
+ */
+public class SearchSuggestionRecyclerView extends RecyclerView implements IWeakRefObject,
+ ISearchSuggestionView, SearchSuggestionVH.OnClickListener {
+
+ private final WeakReference mWeakRef;
+ private final SearchSuggestionAdapter mAdapter;
+ private final SearchSuggestionPresenter mPresenter;
+ private final ItemDecoration mDefaultItemDecoration;
+ private SearchSuggestionVH.OnClickListener mOnSearchSuggestionClickListener;
+ private Call mSearchSuggestionCall;
+
+ public SearchSuggestionRecyclerView(Context context) {
+ this(context, null);
+ }
+
+ public SearchSuggestionRecyclerView(Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SearchSuggestionRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ mWeakRef = new WeakReference<>(context);
+ mPresenter = new SearchSuggestionPresenter(this);
+ mAdapter = new SearchSuggestionAdapter<>(this);
+ mDefaultItemDecoration = new SearchSuggestionItemDecoration(mWeakRef, 4);
+
+ setAdapter(mAdapter);
+ setLayoutManager(new StaggeredGridLayoutManager(1, LinearLayoutManager.HORIZONTAL));
+ addItemDecoration(mDefaultItemDecoration);
+ }
+
+ public void removeDefaultItemDecoration() {
+ removeItemDecoration(mDefaultItemDecoration);
+ }
+
+ @Nullable
+ @Override
+ public Context getRef() {
+ return mWeakRef.get();
+ }
+
+ @NonNull
+ @Override
+ public WeakReference getWeakRef() {
+ return mWeakRef;
+ }
+
+ @Override
+ public boolean hasRef() {
+ return AbstractWeakReferenceUtils.isAlive(mWeakRef);
+ }
+
+ public void getSearchSuggestions(@Nullable String query) {
+
+ if (mSearchSuggestionCall != null && !mSearchSuggestionCall.isCanceled()) {
+ mSearchSuggestionCall.cancel();
+ }
+
+ if (TextUtils.isEmpty(query)) {
+ return;
+ }
+ mSearchSuggestionCall = mPresenter.getSearchSuggestions(query);
+ }
+
+ @Override
+ @CallSuper
+ public void onReceiveSearchSuggestionsSucceeded(@NonNull String query, @NonNull List suggestions) {
+ final boolean expandable = hasRef() && !AbstractListUtils.isEmpty(suggestions);
+ setVisibility(expandable ? VISIBLE : GONE);
+ if (!expandable) {
+ return;
+ }
+ scrollToPosition(0);
+
+ final List list = new ArrayList<>();
+ for (String suggestion : suggestions) {
+ list.add(new SearchSuggestionRVItem(SearchSuggestionAdapter.TYPE_DID_YOU_MEAN_SUGGESTION,
+ query, ColorPalette.getRandomColorResId(list.size()), suggestion));
+ }
+ mAdapter.insert(list);
+ }
+
+ @Override
+ @CallSuper
+ public void onReceiveSearchSuggestionsFailed(@NonNull String query, @Nullable Exception error) {
+ setVisibility(GONE);
+ }
+
+ public void setOnSearchSuggestionClickListener(@Nullable final SearchSuggestionVH.OnClickListener listener) {
+ mOnSearchSuggestionClickListener = listener;
+ mAdapter.setOnSearchSuggestionClickListener(this);
+ }
+
+ @Override
+ @CallSuper
+ public void onClick(int position, @NonNull String query, @NonNull String suggestion) {
+ if (mOnSearchSuggestionClickListener != null) {
+ mOnSearchSuggestionClickListener.onClick(position, query, suggestion);
+ }
+ }
+
+ private static class SearchSuggestionItemDecoration extends ItemDecoration {
+
+ private final WeakReference mWeakRef;
+
+ // note that the item shadow on each side is 4dp
+ private final int mSpaceOnBothEnds;
+ private final int mSpaceBetweenItems;
+
+ /**
+ * @param horizontalGap horizontal gap in dp
+ */
+ private SearchSuggestionItemDecoration(@NonNull WeakReference weakRef,
+ @IntRange(from = 4, to = Integer.MAX_VALUE) int horizontalGap) {
+ mWeakRef = weakRef;
+ // e.g. expected gap is 16dp, then 16 - 4 = mSpaceOnBothEnds
+ mSpaceOnBothEnds = AbstractUIUtils.dpToPx(weakRef.get(), getOrZero(horizontalGap - 4));
+ // e.g. expected gap is 16dp, then 16 - 2 * 4 = mSpaceBetweenItems
+ mSpaceBetweenItems = AbstractUIUtils.dpToPx(weakRef.get(), getOrZero(horizontalGap - 8));
+ }
+
+ private static int getOrZero(int value) {
+ return value > 0 ? value : 0;
+ }
+
+ @Override
+ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+
+ if (!AbstractWeakReferenceUtils.isAlive(mWeakRef)) {
+ return;
+ }
+
+ outRect.left = mSpaceBetweenItems / 2;
+ outRect.top = 0;
+ outRect.right = mSpaceBetweenItems / 2;
+ outRect.bottom = 0;
+
+ final int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewAdapterPosition();
+ final int total = parent.getAdapter().getItemCount();
+ if (position == 0) {
+ outRect.left = mSpaceOnBothEnds;
+ } else if (position == total - 1) {
+ outRect.right = mSpaceOnBothEnds;
+ }
+ }
+ }
+}
+
diff --git a/app/src/main/res/drawable-hdpi/bg_search_suggestion_shadow.9.png b/app/src/main/res/drawable-hdpi/bg_search_suggestion_shadow.9.png
new file mode 100755
index 0000000..a69ae41
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/bg_search_suggestion_shadow.9.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png
new file mode 100644
index 0000000..bbfbc96
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_volume_up_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_volume_up_white_24dp.png
new file mode 100644
index 0000000..57d7871
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_volume_up_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/bg_search_suggestion_shadow.9.png b/app/src/main/res/drawable-mdpi/bg_search_suggestion_shadow.9.png
new file mode 100755
index 0000000..1883687
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/bg_search_suggestion_shadow.9.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png
new file mode 100644
index 0000000..faefc59
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_volume_up_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_volume_up_white_24dp.png
new file mode 100644
index 0000000..7cfd4c7
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_volume_up_white_24dp.png differ
diff --git a/app/src/main/res/drawable-v21/search_suggestion_background.xml b/app/src/main/res/drawable-v21/search_suggestion_background.xml
new file mode 100644
index 0000000..24bbeab
--- /dev/null
+++ b/app/src/main/res/drawable-v21/search_suggestion_background.xml
@@ -0,0 +1,19 @@
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-xhdpi/bg_search_suggestion_shadow.9.png b/app/src/main/res/drawable-xhdpi/bg_search_suggestion_shadow.9.png
new file mode 100755
index 0000000..1728d05
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/bg_search_suggestion_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png
new file mode 100644
index 0000000..bfc3e39
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_volume_up_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_volume_up_white_24dp.png
new file mode 100644
index 0000000..2ed0034
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_volume_up_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/bg_search_suggestion_shadow.9.png b/app/src/main/res/drawable-xxhdpi/bg_search_suggestion_shadow.9.png
new file mode 100755
index 0000000..fb47fda
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/bg_search_suggestion_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png
new file mode 100644
index 0000000..abbb989
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_volume_up_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_volume_up_white_24dp.png
new file mode 100644
index 0000000..2e751a4
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_volume_up_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/bg_search_suggestion_shadow.9.png b/app/src/main/res/drawable-xxxhdpi/bg_search_suggestion_shadow.9.png
new file mode 100755
index 0000000..2efb184
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/bg_search_suggestion_shadow.9.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png
new file mode 100644
index 0000000..dd5adfc
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_volume_up_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_volume_up_white_24dp.png
new file mode 100644
index 0000000..82972b4
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_volume_up_white_24dp.png differ
diff --git a/app/src/main/res/drawable/search_suggestion_background.xml b/app/src/main/res/drawable/search_suggestion_background.xml
new file mode 100644
index 0000000..52297ac
--- /dev/null
+++ b/app/src/main/res/drawable/search_suggestion_background.xml
@@ -0,0 +1,15 @@
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..ff07e4c
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_search.xml b/app/src/main/res/layout/activity_search.xml
new file mode 100644
index 0000000..1f11d6c
--- /dev/null
+++ b/app/src/main/res/layout/activity_search.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/gif_base.xml b/app/src/main/res/layout/gif_base.xml
new file mode 100644
index 0000000..5521a04
--- /dev/null
+++ b/app/src/main/res/layout/gif_base.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/gif_search_no_results.xml b/app/src/main/res/layout/gif_search_no_results.xml
new file mode 100644
index 0000000..fef1d7e
--- /dev/null
+++ b/app/src/main/res/layout/gif_search_no_results.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/gif_search_pivots_view.xml b/app/src/main/res/layout/gif_search_pivots_view.xml
new file mode 100644
index 0000000..8d0664c
--- /dev/null
+++ b/app/src/main/res/layout/gif_search_pivots_view.xml
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_search_suggestion.xml b/app/src/main/res/layout/item_search_suggestion.xml
new file mode 100644
index 0000000..e0b4679
--- /dev/null
+++ b/app/src/main/res/layout/item_search_suggestion.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_tag.xml b/app/src/main/res/layout/item_tag.xml
new file mode 100644
index 0000000..7986af3
--- /dev/null
+++ b/app/src/main/res/layout/item_tag.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..cde69bc
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9a078e3
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c133a0c
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..efc028a
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..bfa42f0
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..3af2608
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..324e72c
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9bec2e6
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..aee44e1
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..34947cd
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-hdpi/dimens.xml b/app/src/main/res/values-hdpi/dimens.xml
new file mode 100644
index 0000000..b3752cf
--- /dev/null
+++ b/app/src/main/res/values-hdpi/dimens.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ 36dp
+
+
+ 18sp
+ 16sp
+
+ 16sp
+
diff --git a/app/src/main/res/values-mdpi/dimens.xml b/app/src/main/res/values-mdpi/dimens.xml
new file mode 100644
index 0000000..cfc12ff
--- /dev/null
+++ b/app/src/main/res/values-mdpi/dimens.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ 36dp
+
+
+ 16sp
+ 14sp
+
+ 16sp
+
diff --git a/app/src/main/res/values-v21/styles.xml b/app/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..8e4681f
--- /dev/null
+++ b/app/src/main/res/values-v21/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values-xhdpi/dimens.xml b/app/src/main/res/values-xhdpi/dimens.xml
new file mode 100644
index 0000000..e6578e9
--- /dev/null
+++ b/app/src/main/res/values-xhdpi/dimens.xml
@@ -0,0 +1,11 @@
+
+
+
+ 48dp
+
+
+ 20sp
+ 18sp
+
+ 18sp
+
diff --git a/app/src/main/res/values-xxhdpi/dimens.xml b/app/src/main/res/values-xxhdpi/dimens.xml
new file mode 100644
index 0000000..0408e7c
--- /dev/null
+++ b/app/src/main/res/values-xxhdpi/dimens.xml
@@ -0,0 +1,7 @@
+
+
+
+ 48dp
+
+ 18sp
+
diff --git a/app/src/main/res/values/color_palette.xml b/app/src/main/res/values/color_palette.xml
new file mode 100644
index 0000000..86bdaf3
--- /dev/null
+++ b/app/src/main/res/values/color_palette.xml
@@ -0,0 +1,16 @@
+
+
+
+ - @color/color_palette_green
+ - @color/color_palette_light_blue
+ - @color/color_palette_yellow
+ - @color/color_palette_deep_purple
+ - @color/color_palette_red
+
+
+ #8BB38B
+ #8BB3B3
+ #B3B38B
+ #8B8BB3
+ #B38B8B
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..1dc6688
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,5 @@
+
+
+ #40000000
+ #73000000
+
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..a2cb12b
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,11 @@
+
+
+
+ 56dp
+
+
+ 14sp
+ 56dp
+
+ 20sp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e9e98bb
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,16 @@
+
+ Tenor Android Demo - Search
+ Search Tenor for GIFs
+ Search Tenor
+ No GIFs were found
+
+ Did you mean?
+
+
+ stop searching
+
+ Clear search
+
+ Enter at least 2 characters to begin the search.
+
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..70d087e
--- /dev/null
+++ b/app/src/main/res/values/styles.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..775421d
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ maven { url 'https://maven.google.com' }
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..aac7c9b
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..76c9020
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Aug 21 10:36:02 PDT 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..034cede
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':app', ':tenor-android-core'
diff --git a/tenor-android-core/build.gradle b/tenor-android-core/build.gradle
new file mode 100644
index 0000000..bf3c496
--- /dev/null
+++ b/tenor-android-core/build.gradle
@@ -0,0 +1,2 @@
+configurations.maybeCreate("default")
+artifacts.add("default", file('tenor-android-core.aar'))
diff --git a/tenor-android-core/tenor-android-core.aar b/tenor-android-core/tenor-android-core.aar
new file mode 100644
index 0000000..88cab3b
Binary files /dev/null and b/tenor-android-core/tenor-android-core.aar differ