package com.konradjanica.amatch; import android.app.ActionBar; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.webkit.WebView; import android.widget.FrameLayout; import android.widget.TextView; import com.andtinder.model.CardModel; import com.andtinder.view.CardContainer; import com.andtinder.view.SimpleCardStackAdapter; import com.facebook.drawee.backends.pipeline.Fresco; import com.konradjanica.Utils; import com.konradjanica.careercup.CareerCupAPI; import com.konradjanica.careercup.questions.Question; import java.util.Iterator; import java.util.LinkedList; import java.util.Locale; import java.util.Queue; import at.markushi.ui.CircleButton; import fr.castorflex.android.smoothprogressbar.SmoothProgressBar; public class MainActivity extends Activity { private final int maxCards = 5; private CardContainer mCardContainerMain; private CardContainer mCardContainerFavorites; private SimpleCardStackAdapter adapterMain; private SimpleCardStackAdapter adapterFavorites; private CareerCupAPI careerCupAPI; private LinkedList<Question> questionsList; private Queue<CardModel> questionsCardQueue; private LinkedList<CardModel> favouritesList; private Queue<CardModel> favoritesCardQueue; // Number of cards displayed private int cardCountMain; private int cardCountFavorite; private int indexFavorite; // From preferences/settings public static int maxFlingSensitivity; private int pageRaw; private String company; private String job; private String topic; private boolean isQuestionsLoading; private boolean isErrorLoading; private SmoothProgressBar progressBar; private TextView noQuestionsText; private boolean isFavoriteMode; // Favourites card file public final static String favoritesFile = "favourites.sav"; private static int settingsChangedIntent = 1; private void init() { careerCupAPI = new CareerCupAPI(); questionsList = new LinkedList<>(); questionsCardQueue = new LinkedList<>(); adapterMain = new SimpleCardStackAdapter(this); cardCountMain = 0; SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); maxFlingSensitivity = Integer.parseInt(preferences.getString("fling_speed", "3")); String page = preferences.getString("page_number", "1"); company = preferences.getString("company_list", ""); job = preferences.getString("job_list", ""); topic = preferences.getString("topic_list", ""); pageRaw = Integer.parseInt(page); new DownloadInitialQuestions().execute(page, company, job, topic); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.activity_main); PreferenceManager.setDefaultValues(this, R.xml.pref_general, false); mCardContainerMain = (CardContainer) findViewById(R.id.main_cards); mCardContainerFavorites = (CardContainer) findViewById(R.id.favorite_cards); progressBar = (SmoothProgressBar) findViewById(R.id.dl_progress); noQuestionsText = (TextView) findViewById(R.id.no_questions_found); isQuestionsLoading = false; isErrorLoading = false; isFavoriteMode = false; favouritesList = Utils.readLinkedListFromFile(getApplicationContext(), favoritesFile); favoritesCardQueue = new LinkedList<>(favouritesList); adapterFavorites = new SimpleCardStackAdapter(this); cardCountFavorite = 0; indexFavorite = 0; ensureFavoritesFull(true); mCardContainerFavorites.setAdapter(adapterFavorites); init(); // Set aMatch button release final CircleButton aMatchButton = ((CircleButton) findViewById(R.id.amatchtoggle)); aMatchButton.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { if (aMatchButton.repeatCount < aMatchButton.ANIMATION_REPEATS) { if (mCardContainerMain.getTopCardView() == null && !isFavoriteMode) { // Reload and parse url when main list is empty final String page = Integer.toString(pageRaw); new DownloadRefillQuestions().execute(page, company, job, topic); } else if (mCardContainerFavorites.getTopCardView() == null && isFavoriteMode) { // Refresh favourites list upon button press favouritesList = Utils.readLinkedListFromFile(getApplicationContext(), favoritesFile); adapterFavorites = new SimpleCardStackAdapter(getApplicationContext()); cardCountFavorite = 0; indexFavorite = 0; favoritesCardQueue = new LinkedList<>(favouritesList); ensureFavoritesFull(true); mCardContainerFavorites.setAdapter(adapterFavorites); } else { // Toggle favourite card CardModel topCard = questionsCardQueue.peek(); View topCardView = mCardContainerMain.getTopCardView(); if (isFavoriteMode) { if (adapterFavorites.getCount() > indexFavorite) { topCard = adapterFavorites.getCardModel(indexFavorite); } topCardView = mCardContainerFavorites.getTopCardView(); } if (topCardView != null) { FrameLayout favView = ((FrameLayout) topCardView.findViewById(R.id.fav)); if (!topCard.isFavorite()) { favView.setVisibility(View.VISIBLE); favouritesList.add(topCard); Utils.writeLinkedListToFile(getApplicationContext(), favouritesList, favoritesFile); } else { favView.setVisibility(View.INVISIBLE); if (favouritesList.size() > 0) { Iterator<CardModel> itr = favouritesList.iterator(); do { CardModel cm = itr.next(); if (cm.getId().equals(topCard.getId())) { itr.remove(); break; } } while (itr.hasNext()); } Utils.writeLinkedListToFile(getApplicationContext(), favouritesList, favoritesFile); } topCard.toggleFavorite(); System.out.println(favouritesList.size()); } } } else { // Toggle favourite mode favouritesList = Utils.readLinkedListFromFile(getApplicationContext(), favoritesFile); if (!isFavoriteMode) { // Change to favourite mode isFavoriteMode = true; adapterFavorites = new SimpleCardStackAdapter(getApplicationContext()); cardCountFavorite = 0; indexFavorite = 0; favoritesCardQueue = new LinkedList<>(favouritesList); ensureFavoritesFull(true); mCardContainerFavorites.setAdapter(adapterFavorites); // Change background color // findViewById(R.id.main_background).setBackgroundColor(getResources().getColor(R.color.amatch)); // Change actionbar color ActionBar bar = getActionBar(); bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.actionbar_bg_fav))); if (Locale.getDefault().getCountry().equals("US")) { bar.setTitle("Favorites"); } else { bar.setTitle("Favourites"); } // Toggle views findViewById(R.id.main_cards).setVisibility(View.GONE); findViewById(R.id.favorite_cards).setVisibility(View.VISIBLE); } else { // Change to main mode isFavoriteMode = false; adapterMain = new SimpleCardStackAdapter(getApplicationContext()); ensureMainFull(); mCardContainerMain.setAdapter(adapterMain); // Change actionbar ActionBar bar = getActionBar(); bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.actionbar_bg))); bar.setTitle("aMatch"); // Toggle views findViewById(R.id.main_cards).setVisibility(View.VISIBLE); findViewById(R.id.favorite_cards).setVisibility(View.GONE); } System.out.println(favouritesList.size()); System.out.println("queue =" + favoritesCardQueue.size()); System.out.println("adapter =" + adapterMain.getCount()); } // Log.d("Released", "Button released"); } return false; } }); } /** * Sets up the adapterMain for first use and populates it with maxCards amount of cards */ private class DownloadInitialQuestions extends AsyncTask<String, Void, Void> { private Exception exception; protected void onPreExecute() { startProgressBar(); } protected Void doInBackground(String... filters) { try { questionsList.addAll(careerCupAPI.loadRecentQuestions(filters)); } catch (Exception e) { this.exception = e; } return null; } protected void onPostExecute(Void dummy) { if (exception != null) { errorProgressBar(); return; } if (questionsList.size() == 0) { mCardContainerMain.setAdapter(adapterMain); stopProgressBar(); return; } Iterator<Question> itr = questionsList.iterator(); // Add cards to adapterMain container addCardInitial(itr); while (itr.hasNext() && cardCountMain < maxCards) { addCardInitial(itr); } stopProgressBar(); mCardContainerMain.setAdapter(adapterMain); } } /** * Used to refill the cards upon pressing aMatch button on connection error */ private class DownloadRefillQuestions extends AsyncTask<String, Void, Void> { private Exception exception; protected void onPreExecute() { startProgressBar(); } protected Void doInBackground(String... filters) { try { questionsList.addAll(careerCupAPI.loadRecentQuestions(filters)); } catch (Exception e) { this.exception = e; } return null; } protected void onPostExecute(Void dummy) { if (exception != null) { errorProgressBar(); return; } ensureFull(); try { mCardContainerMain.refreshTopCard(); } catch (Exception e) { errorProgressBar(); return; } stopProgressBar(); } } /** * Normal download operation, next page is loaded into questionList */ private class DownloadQuestions extends AsyncTask<String, Void, Void> { private Exception exception; protected void onPreExecute() { startProgressBar(); } protected Void doInBackground(String... filters) { try { questionsList.addAll(careerCupAPI.loadRecentQuestions(filters)); } catch (Exception e) { this.exception = e; } return null; } protected void onPostExecute(Void dummy) { if (exception != null) { errorProgressBar(); return; } stopProgressBar(); } } /** * Display download error msg */ private void errorProgressBar() { isQuestionsLoading = false; isErrorLoading = true; progressBar.progressiveStop(); noQuestionsText.setText("Download Error has occurred!\nPlease Try Again."); } /** * Stop download progress bar and display question filter complete msg */ private void stopProgressBar() { isQuestionsLoading = false; isErrorLoading = false; progressBar.progressiveStop(); noQuestionsText.setText("Sorry - no more questions!\nTry new filters"); } /** * Start download progress bar and display loading msg */ private void startProgressBar() { isQuestionsLoading = true; progressBar.progressiveStart(); noQuestionsText.setText("Loading Questions..."); } /** * Add a card without notifying adapterMain * This is the normal procedure for adding files after initial * * @param itr an iterator to the questionsList */ private void addCard(Iterator<Question> itr) { addCard(itr, false); } /** * Add a card while notifying adapterMain * This is the initial procedure for adding files * * @param itr an iterator to the questionsList */ private void addCardInitial(Iterator<Question> itr) { addCard(itr, true); } /** * Add card to adapterMain and add it's listener for adding more cards */ private void addCard(Iterator<Question> itr, boolean isInitial) { Question q = itr.next(); CardModel cardModel = new CardModel(q.company, q.questionText, q.companyImgURL, q.pageNumber, q.dateText + q.location, q.id, q.questionTextLineCount); if (favouritesList.size() > 0) { Iterator<CardModel> iter = favouritesList.iterator(); do { CardModel cm = iter.next(); if (cm.getId().equals(cardModel.getId())) { cardModel.setFavorite(true); break; } } while (iter.hasNext()); } cardModel.setOnCardDimissedListener(new CardModel.OnCardDimissedListener() { @Override public void onLike() { // Log.i("Swipeable Cards", "I like the card"); mainCardRemoval(); ensureFull(); } @Override public void onDislike() { // Log.i("Swipeable Cards", "I dislike the card"); mainCardRemoval(); ensureFull(); } }); // cardModel.setOnClickListener(new CardModel.OnClickListener() { // @Override // public void OnClickListener() { // Log.i("Swipeable Cards", "I am pressing the card"); // } // }); if (isInitial) { adapterMain.addInitial(cardModel); } else { adapterMain.add(cardModel); } ++cardCountMain; itr.remove(); questionsCardQueue.add(cardModel); } /** * Add cards from queue to adapterMain * Used when changing from favourites to main */ private void addCardFromFav(Iterator<CardModel> itr) { CardModel cardModel = itr.next(); cardModel.setFavorite(false); if (favouritesList.size() > 0) { Iterator<CardModel> iter = favouritesList.iterator(); do { CardModel cm = iter.next(); if (cm.getId().equals(cardModel.getId())) { cardModel.setFavorite(true); break; } } while (iter.hasNext()); } cardModel.setOnCardDimissedListener(new CardModel.OnCardDimissedListener() { @Override public void onLike() { // Log.i("Swipeable Cards", "I like the card"); mainCardRemoval(); ensureFull(); } @Override public void onDislike() { // Log.i("Swipeable Cards", "I dislike the card"); mainCardRemoval(); ensureFull(); } }); // cardModel.setOnClickListener(new CardModel.OnClickListener() { // @Override // public void OnClickListener() { // Log.i("Swipeable Cards", "I am pressing the card"); // } // }); adapterMain.addInitial(cardModel); } private void mainCardRemoval() { --cardCountMain; if (questionsCardQueue.size() > 0) { questionsCardQueue.remove(); } } /** * Add card to adapterMain and add it's listener for adding more cards */ private void addCardFavorites(CardModel cardModel, boolean isInitial) { cardModel.setOnCardDimissedListener(new CardModel.OnCardDimissedListener() { @Override public void onLike() { // Log.i("Swipeable Cards", "I like the card"); --cardCountFavorite; ++indexFavorite; ensureFavoritesFull(false); } @Override public void onDislike() { // Log.i("Swipeable Cards", "I dislike the card"); --cardCountFavorite; ++indexFavorite; ensureFavoritesFull(false); } }); // cardModel.setOnClickListener(new CardModel.OnClickListener() { // @Override // public void OnClickListener() { // Log.i("Swipeable Cards", "I am pressing the card"); // } // }); if (isInitial) { adapterFavorites.addInitial(cardModel); } else { adapterFavorites.add(cardModel); } ++cardCountFavorite; } /** * Downloads next page if there's less than (maxCards * 2 - 1) in the list * Also fills 2 cards into adapterMain up to maxCards amount */ private void ensureFull() { if (questionsList.size() < maxCards * 2) { if (!isQuestionsLoading) { if (!isErrorLoading) { ++pageRaw; } final String page = Integer.toString(pageRaw); new DownloadQuestions().execute(page, company, job, topic); } } if (questionsList.size() > 0) { // Add cards until full Iterator<Question> itr = questionsList.iterator(); addCard(itr); if (itr.hasNext() && cardCountMain < maxCards) { addCard(itr); } } System.out.println("page = " + pageRaw + " questionsList size = " + questionsList.size()); } /** * Fills 2 cards into adapterFavourites up to maxCards amount */ private void ensureFavoritesFull(boolean isInitial) { if (favoritesCardQueue.size() > 0 && cardCountFavorite < maxCards) { // Add cards until full addCardFavorites(favoritesCardQueue.poll(), isInitial); if (favoritesCardQueue.size() > 0 && cardCountFavorite < maxCards) { addCardFavorites(favoritesCardQueue.poll(), isInitial); } } // System.out.println("page = " + pageRaw + " questionsList size = " + questionsList.size()); } /** * Fills cards into adapterMain from cardQueue */ private void ensureMainFull() { if (questionsCardQueue.size() > 0) { Iterator<CardModel> itr = questionsCardQueue.iterator(); do { addCardFromFav(itr); } while (itr.hasNext()); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); // return true; return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); // Drawable gearup = getResources().getDrawable(R.drawable.gearup); // item.setIcon(gearup); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { // Drawable gearDown = getResources().getDrawable(R.drawable.ic_launcher); // item.setIcon(gearDown); SettingsActivity.applyPressed = false; Intent myIntent = new Intent(this, SettingsActivity.class); startActivityForResult(myIntent, settingsChangedIntent); return true; } return super.onOptionsItemSelected(item); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (SettingsActivity.applyPressed) { init(); } } @Override public void onBackPressed() { // RetrieveLastCard will put previously destroyed card // on the top of current card container stack // else just use normal back button if (isFavoriteMode) { // Close webview if open // else retreive card WebView webView = (WebView) mCardContainerFavorites.getTopCardView().findViewById(R.id.web); if (webView.getVisibility() == View.VISIBLE) { webView.setVisibility(View.GONE); mCardContainerFavorites.getTopCardView().findViewById(R.id.description).setVisibility(View.VISIBLE); } else { mCardContainerFavorites.retrieveLastCard(); } } else { // Close webview if open // else retreive card WebView webView = (WebView) mCardContainerMain.getTopCardView().findViewById(R.id.web); if (webView.getVisibility() == View.VISIBLE) { webView.setVisibility(View.GONE); mCardContainerMain.getTopCardView().findViewById(R.id.description).setVisibility(View.VISIBLE); } else { mCardContainerMain.retrieveLastCard(); } } } @Override public boolean onKeyLongPress(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { super.onBackPressed(); } return super.onKeyLongPress(keyCode, event); } }