/* Copyright (C) 2014 Prasanna Thirumalai This file is part of StackX. StackX is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. StackX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with StackX. If not, see <http://www.gnu.org/licenses/>. */ package com.prasanna.android.stacknetwork; import java.util.HashMap; import android.app.ActionBar; import android.app.ActionBar.Tab; import android.app.Fragment; import android.app.FragmentTransaction; import android.app.SearchManager; import android.content.Intent; import android.database.SQLException; import android.os.Bundle; import android.provider.SearchRecentSuggestions; import android.view.Menu; import android.view.MenuItem; import android.widget.Toast; import com.prasanna.android.provider.RecentQueriesProvider; import com.prasanna.android.stacknetwork.fragment.QuestionListFragment; import com.prasanna.android.stacknetwork.fragment.TagListFragment; import com.prasanna.android.stacknetwork.fragment.TagListFragment.OnTagSelectListener; import com.prasanna.android.stacknetwork.model.SearchCriteria; import com.prasanna.android.stacknetwork.service.QuestionsIntentService; import com.prasanna.android.stacknetwork.sqlite.TagDAO; import com.prasanna.android.stacknetwork.utils.DbRequestThreadExecutor; import com.prasanna.android.stacknetwork.utils.OperatingSite; import com.prasanna.android.stacknetwork.utils.SharedPreferencesUtil; import com.prasanna.android.stacknetwork.utils.StackUri.Sort; import com.prasanna.android.stacknetwork.utils.StringConstants; public class QuestionsActivity extends AbstractUserActionBarActivity implements OnTagSelectListener { private static final String TAB_TITLE_ACTIVE = "Active"; private static final String TAB_TITLE_NEW = "New"; private static final String TAB_TITLE_FEATURED = "Featured"; private static final String TAB_TITLE_MOST_VOTED = "Most Voted"; private static final String TAB_TITLE_FAQ = "FAQ"; private static final String LAST_SELECTED_TAB = "last_selected_tab"; private static QuestionsActivity self; private boolean showTagsFragment = false; private TagListFragment tagListFragment; private String intentAction; private String tag; private int action; public static QuestionListFragment getFragment(String fragmentTag) { if (self != null) return (QuestionListFragment) self.getFragmentManager().findFragmentByTag(fragmentTag); else return null; } public class TabListener implements ActionBar.TabListener { private final QuestionListFragment fragment; public TabListener(QuestionListFragment fragment) { this.fragment = fragment; } public void onTabSelected(Tab tab, FragmentTransaction ft) { Fragment existingFragment = getFragmentManager().findFragmentByTag(fragment.fragmentTag); ft.setCustomAnimations(R.anim.slide_in_left, 0); if (existingFragment == null) ft.add(R.id.fragmentContainer, fragment, fragment.fragmentTag); else ft.attach(existingFragment); } public void onTabUnselected(Tab tab, FragmentTransaction ft) { ft.setCustomAnimations(0, R.anim.slide_out_left); ft.remove(fragment); } public void onTabReselected(Tab tab, FragmentTransaction ft) { } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); self = this; setContentView(R.layout.fragment_container); if (savedInstanceState != null) { action = savedInstanceState.getInt(StringConstants.ACTION, 0); if (action != 0) { if (action == QuestionsIntentService.GET_QUESTIONS_FOR_TAG) showLastTagQuestionListFragment(savedInstanceState); else showFrontPageForSite(); int lastSelectedTab = savedInstanceState.getInt(LAST_SELECTED_TAB, 0); if (lastSelectedTab > 0) getActionBar().setSelectedNavigationItem(lastSelectedTab); } } } private void showFrontPageForSite() { showTagsFragment = true; getActionBar().setDisplayHomeAsUpEnabled(true); setupActionBarTabs(QuestionsIntentService.GET_FRONT_PAGE, OperatingSite.getSite().name, true); } private void showLastTagQuestionListFragment(Bundle savedInstanceState) { showTagsFragment = true; getActionBar().setDisplayHomeAsUpEnabled(true); setupActionBarTabs(action, savedInstanceState.getString(StringConstants.TAG), false); } private void setupActionBarTabs(int action, String tag, boolean frontPage) { getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); this.action = action; this.tag = tag; createTab(TAB_TITLE_ACTIVE, QuestionListFragment.newFragment(action, tag, Sort.ACTIVITY), true); createTab(TAB_TITLE_NEW, QuestionListFragment.newFragment(action, tag, Sort.CREATION), false); createTab(TAB_TITLE_FEATURED, QuestionListFragment.newFragment(QuestionsIntentService.GET_FEATURED, tag), false); createTab(TAB_TITLE_MOST_VOTED, QuestionListFragment.newFragment(action, tag, Sort.VOTES), false); if (!frontPage) { createTab(TAB_TITLE_FAQ, QuestionListFragment.newFragment(QuestionsIntentService.GET_FAQ_FOR_TAG, tag, null), false); } else { HashMap<String, SearchCriteria> customTabs = DbRequestThreadExecutor.getSearchesMarkedForTab(getApplicationContext(), OperatingSite.getSite().apiSiteParameter); if (customTabs != null) { for (String key : customTabs.keySet()) createTab(key, QuestionListFragment.newFragment(key, customTabs.get(key)), false); } } } private void createTab(String title, QuestionListFragment fragment, boolean setSelected) { Tab tab = getActionBar().newTab(); tab.setText(title).setTabListener(new TabListener(fragment)); getActionBar().addTab(tab, setSelected); } @Override public void onSaveInstanceState(Bundle outState) { removeTagListFragment(); if (getActionBar().getNavigationMode() == ActionBar.NAVIGATION_MODE_TABS) outState.putInt(LAST_SELECTED_TAB, getActionBar().getSelectedNavigationIndex()); outState.putInt(StringConstants.ACTION, action); outState.putString(StringConstants.TAG, tag); super.onSaveInstanceState(outState); } private void removeTagListFragment() { if (tagListFragment != null) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.remove(tagListFragment); ft.commit(); tagListFragment = null; } } @Override public void onResume() { super.onResume(); if (getActionBar().getTabCount() == 0) showFragmentForIntentAction(); else { Fragment fragment = getFragmentManager().findFragmentById(R.id.fragmentContainer); if (fragment != null) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.show(fragment); ft.commit(); } else { if (getIntent().getAction() == null || StringConstants.TAG.equals(getIntent().getAction())) { getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); getActionBar().setDisplayHomeAsUpEnabled(true); getActionBar().setSelectedNavigationItem(0); } } } } private void showFragmentForIntentAction() { intentAction = getIntent().getAction(); if (Intent.ACTION_SEARCH.equals(intentAction)) showSearchFragment(); else if (StringConstants.SIMILAR.equals(intentAction)) showSimilarQuestionListFragment(); else if (StringConstants.RELATED.equals(intentAction)) showRelatedQuestionListFragment(); else if (StringConstants.TAG.equals(intentAction)) showTagQuestionListFragment(); else showFrontPageForSite(); } private void showSearchFragment() { String query = getIntent().getStringExtra(SearchManager.QUERY); saveSearchQuery(query); String fragmentTag = "search -" + query; QuestionListFragment questionListFragment = getFragment(fragmentTag); if (questionListFragment == null) questionListFragment = QuestionListFragment.newFragment(QuestionsIntentService.SEARCH, query, null); replaceFragment(questionListFragment, fragmentTag, false); } private void saveSearchQuery(String query) { SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this, RecentQueriesProvider.AUTHORITY, RecentQueriesProvider.MODE); suggestions.saveRecentQuery(query, null); } private void showSimilarQuestionListFragment() { String title = getIntent().getStringExtra(StringConstants.TITLE); String fragmentTag = QuestionsIntentService.GET_SIMILAR + "-" + title.hashCode(); setActionBarTitle(getString(R.string.similar) + " to " + title); QuestionListFragment questionListFragment = getFragment(fragmentTag); if (questionListFragment == null) { questionListFragment = QuestionListFragment.newFragment(QuestionsIntentService.GET_SIMILAR, fragmentTag); questionListFragment.getBundle().putString(StringConstants.TITLE, title); replaceFragment(questionListFragment, fragmentTag, false); } } private void showRelatedQuestionListFragment() { long questionId = getIntent().getLongExtra(StringConstants.QUESTION_ID, 0); String fragmentTag = QuestionsIntentService.GET_RELATED + "-" + questionId; QuestionListFragment questionListFragment = getFragment(fragmentTag); if (questionListFragment == null) { questionListFragment = QuestionListFragment.newFragment(QuestionsIntentService.GET_RELATED, fragmentTag); questionListFragment.getBundle().putLong(StringConstants.QUESTION_ID, questionId); replaceFragment(questionListFragment, fragmentTag, false); } } private void showTagQuestionListFragment() { String tag = getIntent().getStringExtra(StringConstants.TAG); setupActionBarTabs(QuestionsIntentService.GET_QUESTIONS_FOR_TAG, tag, false); } @Override public void onBackPressed() { if (!hideTagFragmentIfShown()) super.onBackPressed(); } private boolean hideTagFragmentIfShown() { Fragment currentFragment = getFragmentManager().findFragmentById(R.id.fragmentContainer); if (currentFragment instanceof TagListFragment) { hideTagFragment(); toggleDisplayForTags(false); return true; } return false; } @Override public boolean onCreateOptionsMenu(Menu menu) { boolean ret = super.onCreateOptionsMenu(menu); if (menu != null && intentAction != null && StringConstants.TAG.equals(intentAction)) menu.findItem(R.id.menu_new_label).setVisible(true); return ret; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (intentAction != null && StringConstants.TAG.equals(intentAction)) { if (item.getItemId() == R.id.menu_new_label) { insertTagToDb(); return true; } } return super.onOptionsItemSelected(item); } private void insertTagToDb() { TagDAO tagDAO = new TagDAO(this); String tagLabel = getIntent().getStringExtra(StringConstants.TAG); try { tagDAO.open(); tagDAO.insert(OperatingSite.getSite().apiSiteParameter, tagLabel, true); Toast.makeText(this, tagLabel + " added to your tags", Toast.LENGTH_LONG).show(); SharedPreferencesUtil.setBoolean(this, TagListFragment.TAGS_DIRTY, true); } catch (SQLException e) { Toast.makeText(this, "Failed to add " + tagLabel + " to your tags", Toast.LENGTH_LONG).show(); } finally { tagDAO.close(); } } @Override public void refresh() { QuestionListFragment questionsFragment = (QuestionListFragment) getFragmentManager().findFragmentById(R.id.fragmentContainer); questionsFragment.refresh(); } @Override protected boolean shouldSearchViewBeEnabled() { return true; } @Override protected boolean onActionBarHomeButtonClick(MenuItem menuItem) { if (showTagsFragment && menuItem.getItemId() == android.R.id.home) { tagListFragment = (TagListFragment) getFragmentManager().findFragmentByTag(StringConstants.TAGS); if (tagListFragment == null) { tagListFragment = TagListFragment.newFragment(this); addAndHideFragment(tagListFragment, StringConstants.TAGS); } else tagListFragment.setOnTagSelectListener(this); toggleDisplayForTags(true); showTagFragment(); return true; } return super.onActionBarHomeButtonClick(menuItem); } private void toggleDisplayForTags(boolean forTags) { getActionBar().setDisplayHomeAsUpEnabled(!forTags); if (forTags) { getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); setActionBarTitle(StringConstants.TAGS); } else getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBarMenu.findItem(R.id.menu_search).setVisible(!forTags); actionBarMenu.findItem(R.id.menu_refresh).setVisible(!forTags); } @Override public void onFrontPageSelected() { hideTagFragment(); setupTabsForTag(QuestionsIntentService.GET_FRONT_PAGE, OperatingSite.getSite().name, true); } @Override public void onTagSelected(String tag) { hideTagFragment(); setupTabsForTag(QuestionsIntentService.GET_QUESTIONS_FOR_TAG, tag, false); } private void addAndHideFragment(TagListFragment fragment, String fragmentTag) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.add(R.id.fragmentContainer, fragment, fragmentTag); ft.hide(fragment); ft.commit(); } private void setupTabsForTag(int action, String newTag, boolean frontPage) { toggleDisplayForTags(false); if (tag == null || !tag.equals(newTag)) { getActionBar().removeAllTabs(); setupActionBarTabs(action, newTag, frontPage); } } private void showTagFragment() { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(R.anim.slide_in_left, 0); ft.show(tagListFragment); ft.commit(); } private void hideTagFragment() { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(0, R.anim.slide_out_left); ft.hide(tagListFragment); ft.commit(); getFragmentManager().executePendingTransactions(); } private void replaceFragment(Fragment fragment, String fragmentTag, boolean addToBackStack) { FragmentTransaction ft = getFragmentManager().beginTransaction(); ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out); ft.replace(R.id.fragmentContainer, fragment, fragmentTag); if (addToBackStack) ft.addToBackStack(fragmentTag); ft.commit(); } }