diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d408354..b5b56df 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -20,6 +20,7 @@
+
diff --git a/app/src/main/java/io/saytheirnames/activity/HomeSearchActivity.java b/app/src/main/java/io/saytheirnames/activity/HomeSearchActivity.java
new file mode 100644
index 0000000..902d87d
--- /dev/null
+++ b/app/src/main/java/io/saytheirnames/activity/HomeSearchActivity.java
@@ -0,0 +1,298 @@
+package io.saytheirnames.activity;
+
+import android.annotation.SuppressLint;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentTransaction;
+import androidx.paging.LoadState;
+import androidx.paging.LoadStateAdapter;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.MergeAdapter;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.google.android.material.appbar.AppBarLayout;
+import com.squareup.picasso.Picasso;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.saytheirnames.R;
+import io.saytheirnames.adapters.HashtagAdapter;
+import io.saytheirnames.adapters.HeaderCardRecyclerAdapter;
+import io.saytheirnames.adapters.HomeHeaderAdapter;
+import io.saytheirnames.adapters.MediaAdapter;
+import io.saytheirnames.adapters.NewsAdapter;
+import io.saytheirnames.adapters.PeopleAdapter;
+import io.saytheirnames.adapters.PeopleSearchAdapter;
+import io.saytheirnames.fragments.DonationFragment;
+import io.saytheirnames.models.Hashtag;
+import io.saytheirnames.models.Media;
+import io.saytheirnames.models.News;
+import io.saytheirnames.models.People;
+import io.saytheirnames.models.PeopleData;
+import io.saytheirnames.network.BackendInterface;
+import io.saytheirnames.network.Utils;
+import io.saytheirnames.utils.CustomTabUtil;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+public class HomeSearchActivity extends AppCompatActivity implements HeaderCardRecyclerAdapter.HeaderCardClickListener {
+
+ public static final String EXTRA_ID = "identifier";
+
+ private AppBarLayout appBarLayout;
+ private LinearLayout linearLayout;
+ private LinearLayout search_message;
+ private LinearLayout search_no_record;
+ private EditText search_text;
+ private TextView cancelText;
+
+ private MediaAdapter mediaAdapter;
+ private NewsAdapter newsAdapter;
+ private HashtagAdapter hashtagAdapter;
+
+ private List newsList;
+ private List mediaList;
+ private List hashtagList;
+
+ private ArrayList peopleList;
+
+ private String personID, baseUrl;
+
+ PeopleData peopleData;
+
+ BackendInterface backendInterface;
+ ;
+
+ private RecyclerView personRecyclerView;
+ private MergeAdapter mergeAdapter;
+
+ private PeopleAdapter peopleAdapter;
+ private PeopleSearchAdapter peopleSearchAdapter;
+ private ProgressBar progressBar;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_home_search);
+
+ personID = getIntent().getStringExtra(EXTRA_ID);
+ peopleData = new PeopleData();
+
+ bindViews();
+ initializeRecyclerView();
+ }
+
+ @SuppressLint("StaticFieldLeak")
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ //clear Glide's disk cache whenever an activity is destroyed. Mechanism for helping against memory leaks/ Out of memory errors
+ new AsyncTask() {
+ @Override
+ protected Void doInBackground(Void... voids) {
+ // This method must be called on a background thread.
+ Glide.get(getApplicationContext()).clearDiskCache();
+
+ // DetailsActivity's richLinkViewer (in the NewsAdapter) internally uses Picasso
+ Picasso.get().shutdown();
+ return null;
+ }
+ };
+ }
+
+ private void initializeBackend() {
+ backendInterface = Utils.getBackendService();
+ }
+
+ private void bindViews() {
+ personRecyclerView = findViewById(R.id.personRecyclerView);
+ progressBar = findViewById(R.id.progressBar);
+ appBarLayout = findViewById(R.id.app_bar_home);
+ search_message = findViewById(R.id.search_message);
+ search_no_record = findViewById(R.id.search_no_record);
+ linearLayout = appBarLayout.findViewById(R.id.linear);
+ search_text = linearLayout.findViewById(R.id.search_text);
+ cancelText = linearLayout.findViewById(R.id.cancel);
+
+ peopleAdapter = new PeopleAdapter();
+ peopleList = new ArrayList<>();
+ peopleSearchAdapter = new PeopleSearchAdapter(peopleList, HomeSearchActivity.this);
+
+
+ mergeAdapter = new MergeAdapter(new HomeHeaderAdapter(this), peopleAdapter);
+
+
+ cancelText.setOnClickListener(v -> {
+ finish();
+ });
+
+ search_text.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ loadData(s.toString());
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+
+ }
+ });
+
+ }
+
+ private void initializeRecyclerView() {
+ GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 1);
+
+ /*
+ This makes the first item span two columns (the black cards)
+ */
+ gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
+ @Override
+ public int getSpanSize(int position) {
+ return 1;
+ //return position == 0 ? 2 : 1;
+ }
+ });
+
+ /*
+ This triggers the showing/hiding of the progress bar. This looks really hacky
+ this way, though.
+ */
+
+ peopleAdapter.withLoadStateFooter(new LoadStateAdapter() {
+ @NotNull
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(@NotNull ViewGroup viewGroup, @NotNull LoadState loadState) {
+ return new RecyclerView.ViewHolder(progressBar) {
+ };
+ }
+
+ @Override
+ public void onBindViewHolder(@NotNull RecyclerView.ViewHolder viewHolder, @NotNull LoadState loadState) {
+ if (loadState.equals(LoadState.Loading.INSTANCE)) {
+ progressBar.setVisibility(View.VISIBLE);
+ } else {
+ progressBar.setVisibility(View.GONE);
+ }
+ }
+ });
+
+ personRecyclerView.setLayoutManager(gridLayoutManager);
+ personRecyclerView.setAdapter(peopleSearchAdapter);
+ }
+
+ private void loadData(String s) {
+ showProgress(true);
+ showNoRecord(false);
+ showSearchMessage(false);
+ peopleList.clear();
+ if (s.length() == 0) {
+ showProgress(false);
+ showNoRecord(false);
+ showSearchMessage(true);
+ peopleSearchAdapter.notifyDataSetChanged();
+ } else {
+ BackendInterface backendInterface = Utils.getBackendService();
+ backendInterface.searchPeople(s).enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull Response response) {
+ if (response.isSuccessful()) {
+ showProgress(false);
+ if (response.body() != null) {
+ if (response.body().getData().size() == 0) {
+ showNoRecord(true);
+ showSearchMessage(false);
+ } else {
+ showNoRecord(false);
+ showSearchMessage(false);
+ peopleList.addAll(response.body().getData());
+ }
+ }
+ peopleSearchAdapter.notifyDataSetChanged();
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable t) {
+ showProgress(false);
+ showNoRecord(false);
+ showSearchMessage(true);
+ onGetPersonFailure(t);
+ }
+ });
+ }
+
+
+ }
+
+ private void onGetPersonFailure(Throwable throwable) {
+ //TODO: Get a better message. This could be full of dev jargon.
+ showSnackbar(throwable.getLocalizedMessage());
+ }
+
+ private void showSnackbar(String text) {
+ // Snackbar.make(toolbar, text, Snackbar.LENGTH_SHORT).show();
+ }
+
+
+ private void showProgress(Boolean show) {
+ progressBar.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+
+ private void showSearchMessage(Boolean show) {
+ search_message.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+
+ private void showNoRecord(Boolean show) {
+ search_no_record.setVisibility(show ? View.VISIBLE : View.GONE);
+ }
+
+ @Override
+ public void onHeaderClick() {
+
+ Fragment donationFragment = DonationFragment.newInstance();
+ String tag = "DonationFragment";
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ ft.replace(R.id.container, donationFragment, tag);
+ ft.commit();
+ ((MainActivity) getBaseContext()).updateBottomNavBasedOnTag(tag);
+ }
+
+
+ private String nullCheck(Integer inputString) {
+ if (inputString == null) {
+ return "N/A";
+ } else {
+ return inputString.toString();
+ }
+ }
+
+ private void navigateToUrl(String url) {
+ CustomTabUtil.openCustomTabForUrl(this, url);
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/saytheirnames/adapters/NewsAdapter.java b/app/src/main/java/io/saytheirnames/adapters/NewsAdapter.java
index 6acb411..712a4e3 100644
--- a/app/src/main/java/io/saytheirnames/adapters/NewsAdapter.java
+++ b/app/src/main/java/io/saytheirnames/adapters/NewsAdapter.java
@@ -49,6 +49,7 @@ public void onSuccess(boolean status) {
}
@Override
public void onError(Exception e) {
+ Log.d("ERROR:::", String.valueOf(e.getLocalizedMessage()));
}
});
diff --git a/app/src/main/java/io/saytheirnames/adapters/PeopleSearchAdapter.java b/app/src/main/java/io/saytheirnames/adapters/PeopleSearchAdapter.java
new file mode 100644
index 0000000..74d7790
--- /dev/null
+++ b/app/src/main/java/io/saytheirnames/adapters/PeopleSearchAdapter.java
@@ -0,0 +1,86 @@
+package io.saytheirnames.adapters;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.cardview.widget.CardView;
+import androidx.recyclerview.widget.RecyclerView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import io.saytheirnames.R;
+import io.saytheirnames.activity.DetailsActivity;
+import io.saytheirnames.models.People;
+import io.saytheirnames.models.PeopleData;
+import io.saytheirnames.models.Person;
+
+public class PeopleSearchAdapter extends RecyclerView.Adapter {
+
+ private List peopleList;
+ private Context context;
+
+
+ public PeopleSearchAdapter(List peopleList, Context context) {
+ super();
+ this.peopleList = peopleList;
+ this.context = context;
+
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public PeopleSearchAdapter.FilterItemHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+
+ View convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.person_search_item, parent, false);
+
+
+ return new FilterItemHolder(convertView);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull PeopleSearchAdapter.FilterItemHolder holder, final int position) {
+
+ People people = peopleList.get(position);
+
+ holder.personName.setText(people.getFullName());
+
+
+ holder.cardView.setOnClickListener(v -> {
+ ((Activity)context).finish();
+ Intent intent = new Intent(context, DetailsActivity.class);
+ intent.putExtra(DetailsActivity.EXTRA_ID, people.getIdentifier());
+ holder.itemView.getContext().startActivity(intent);
+ });
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public int getItemCount() {
+ return peopleList.size();
+ }
+
+ static class FilterItemHolder extends RecyclerView.ViewHolder {
+ TextView personName;
+ CardView cardView;
+
+ public FilterItemHolder(@NonNull View itemView) {
+ super(itemView);
+ personName = itemView.findViewById(R.id.txtPersonName);
+ cardView = itemView.findViewById(R.id.cardView);
+ }
+ }
+}
diff --git a/app/src/main/java/io/saytheirnames/fragments/HomeFragment.java b/app/src/main/java/io/saytheirnames/fragments/HomeFragment.java
index 0df05a8..ad6f622 100644
--- a/app/src/main/java/io/saytheirnames/fragments/HomeFragment.java
+++ b/app/src/main/java/io/saytheirnames/fragments/HomeFragment.java
@@ -1,13 +1,18 @@
package io.saytheirnames.fragments;
+import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageButton;
import android.widget.ProgressBar;
+import android.widget.RelativeLayout;
+import android.widget.Toast;
import androidx.annotation.Nullable;
+import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.paging.LoadState;
@@ -16,11 +21,14 @@
import androidx.recyclerview.widget.MergeAdapter;
import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.appbar.AppBarLayout;
+
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import io.saytheirnames.R;
+import io.saytheirnames.activity.HomeSearchActivity;
import io.saytheirnames.activity.MainActivity;
import io.saytheirnames.adapters.FilterHomeAdapter;
import io.saytheirnames.adapters.HeaderCardRecyclerAdapter;
@@ -43,6 +51,11 @@ public class HomeFragment extends Fragment implements HeaderCardRecyclerAdapter.
private ArrayList filterArrayList;
private ProgressBar progressBar;
+ private AppBarLayout appBarLayout;
+ private Toolbar toolbar;
+ private RelativeLayout relativeLayout;
+ private ImageButton searchButton;
+
Resources resources;
public static HomeFragment newInstance() {
@@ -67,6 +80,12 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
personRecyclerView = mContent.findViewById(R.id.personRecyclerView);
progressBar = mContent.findViewById(R.id.progressBar);
+ appBarLayout = mContent.findViewById(R.id.app_bar_home);
+ toolbar = appBarLayout.findViewById(R.id.toolbar);
+ relativeLayout = toolbar.findViewById(R.id.relative_layout);
+ searchButton = relativeLayout.findViewById(R.id.searchButton);
+
+
peopleAdapter = new PeopleAdapter();
@@ -74,12 +93,21 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container,
filterHomeAdapter = new FilterHomeAdapter(filterArrayList, getActivity());
+ searchButton.setOnClickListener(v -> {
+ doSearch();
+ });
+
initializeRecyclerView();
loadData();
return mContent;
}
+ private void doSearch(){
+ Intent intent = new Intent(getActivity(), HomeSearchActivity.class);
+ startActivity(intent);
+ }
+
private void initializeRecyclerView() {
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 2);
diff --git a/app/src/main/java/io/saytheirnames/network/BackendInterface.java b/app/src/main/java/io/saytheirnames/network/BackendInterface.java
index 436eafd..76ccdb2 100644
--- a/app/src/main/java/io/saytheirnames/network/BackendInterface.java
+++ b/app/src/main/java/io/saytheirnames/network/BackendInterface.java
@@ -17,6 +17,9 @@ public interface BackendInterface {
@GET("/api/people")
Call getPeople(@Query("page") Integer page);
+ @GET("/api/people")
+ Call searchPeople(@Query("name") String name);
+
@GET("/api/people/{id}")
Call getPeopleById(@Path("id") String id);
diff --git a/app/src/main/res/drawable/shadow.xml b/app/src/main/res/drawable/shadow.xml
new file mode 100644
index 0000000..82d5bae
--- /dev/null
+++ b/app/src/main/res/drawable/shadow.xml
@@ -0,0 +1,48 @@
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_home_search.xml b/app/src/main/res/layout/activity_home_search.xml
new file mode 100644
index 0000000..8a9c3e6
--- /dev/null
+++ b/app/src/main/res/layout/activity_home_search.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index 2fda1ec..871c90d 100644
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -21,6 +21,7 @@
app:layout_scrollFlags="scroll|enterAlways">
@@ -62,6 +63,7 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index cf3ec7e..9cf344a 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -7,4 +7,5 @@
0dp
4dp
16dp
+ 24dp
\ No newline at end of file