/* * Copyright (C) 2012 Alex Kuiper * * This file is part of PageTurner * * PageTurner 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. * * PageTurner 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 PageTurner. If not, see <http://www.gnu.org/licenses/>.* */ package net.nightwhistler.pageturner.activity; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.widget.Toast; import com.google.inject.Inject; import com.google.inject.Provider; import jedi.option.Option; import net.nightwhistler.nucular.atom.AtomConstants; import net.nightwhistler.nucular.atom.Entry; import net.nightwhistler.nucular.atom.Feed; import net.nightwhistler.nucular.atom.Link; import net.nightwhistler.pageturner.Configuration; import net.nightwhistler.pageturner.CustomOPDSSite; import net.nightwhistler.pageturner.R; import net.nightwhistler.pageturner.catalog.*; import net.nightwhistler.pageturner.fragment.BookDetailsFragment; import net.nightwhistler.pageturner.fragment.CatalogFragment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import roboguice.inject.InjectFragment; import javax.annotation.Nullable; import java.util.List; import static jedi.functional.FunctionalPrimitives.isEmpty; import static jedi.option.Options.none; import static jedi.option.Options.option; public class CatalogActivity extends PageTurnerActivity implements CatalogParent { private static final Logger LOG = LoggerFactory .getLogger("CatalogActivity"); @Nullable @InjectFragment(R.id.fragment_book_details) private BookDetailsFragment detailsFragment; @Inject private Provider<CatalogFragment> fragmentProvider; @Inject private FragmentManager fragmentManager; @Inject private Configuration config; private String baseFeedTitle; @Override protected void onCreatePageTurnerActivity(Bundle savedInstanceState) { hideDetailsView(); loadFeed( null, config.getBaseOPDSFeed(), null, false ); fragmentManager.addOnBackStackChangedListener( this::onBackStackChanged ); } @Override protected int getMainLayoutResource() { return R.layout.activity_catalog; } private void hideDetailsView() { if ( detailsFragment != null ) { FragmentTransaction ft = fragmentManager.beginTransaction(); ft.hide(detailsFragment); ft.commitAllowingStateLoss(); } } private boolean isTwoPaneView() { return getResources().getConfiguration().orientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE && detailsFragment != null; } @Override public void onFeedLoaded(Feed feed) { if ( isTwoPaneView() && feed.getSize() == 1 && feed.getEntries().get(0).getEpubLink() != null ) { loadFakeFeed(feed); } else { hideDetailsView(); } supportInvalidateOptionsMenu(); getSupportActionBar().setTitle(feed.getTitle()); LOG.debug( "Changed window title to " + feed.getTitle() ); /* * Work-around, since the initial fragment isn't put on * the back-stack. We do want to restore its title * when the stack becomes empty, so we save it here. */ if ( fragmentManager.getBackStackEntryCount() == 0 ) { this.baseFeedTitle = feed.getTitle(); } } private void onBackStackChanged() { LOG.debug( "Backstack change detected." ); if ( fragmentManager.getBackStackEntryCount() > 0 ) { Option<Fragment> fragmentOption = getCurrentVisibleFragment(); fragmentOption.forEach( (fragment) -> { if ( fragment instanceof CatalogFragment ) { LOG.debug( "Notifying fragment."); ((CatalogFragment) fragment).onBecameVisible(); } }); } else if ( baseFeedTitle != null ) { supportInvalidateOptionsMenu(); getSupportActionBar().setTitle( baseFeedTitle); } } @Override public void loadFakeFeed(Feed fakeFeed) { if ( isTwoPaneView() ) { FragmentTransaction ft = fragmentManager.beginTransaction(); ft.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right); ft.show(detailsFragment); ft.commit(); detailsFragment.setNewFeed(fakeFeed, null); } else { Intent intent = new Intent( this, CatalogBookDetailsActivity.class ); intent.putExtra("fakeFeed", fakeFeed); startActivity(intent); } } @Override public void loadCustomSitesFeed() { List<CustomOPDSSite> sites = config.getCustomOPDSSites(); if ( sites.isEmpty() ) { Toast.makeText(this, R.string.no_custom_sites, Toast.LENGTH_LONG).show(); return; } CatalogFragment newCatalogFragment = fragmentProvider.get(); Feed customSites = new Feed(); customSites.setURL(Catalog.CUSTOM_SITES_ID); customSites.setTitle(getString(R.string.custom_site)); for ( CustomOPDSSite site: sites ) { Entry entry = new Entry(); entry.setTitle(site.getName()); entry.setSummary(site.getDescription()); Link link = new Link(site.getUrl(), AtomConstants.TYPE_ATOM, AtomConstants.REL_BUY, null); entry.addLink(link); entry.setBaseURL(site.getUrl()); customSites.addEntry(entry); } customSites.setId(Catalog.CUSTOM_SITES_ID); newCatalogFragment.setStaticFeed( customSites ); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right); fragmentTransaction.replace(R.id.fragment_catalog, newCatalogFragment, Catalog.CUSTOM_SITES_ID ); fragmentTransaction.addToBackStack( Catalog.CUSTOM_SITES_ID ); fragmentTransaction.commit(); } @Override public void loadFeed(Entry entry, String href, String baseURL, boolean asDetailsFeed) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right); CatalogFragment newCatalogFragment = fragmentProvider.get(); newCatalogFragment.setBaseURL( baseURL ); fragmentTransaction.replace(R.id.fragment_catalog, newCatalogFragment, baseURL); if ( ! href.equals( config.getBaseOPDSFeed() ) ) { fragmentTransaction.addToBackStack( baseURL ); } fragmentTransaction.commit(); newCatalogFragment.loadURL(entry, href, asDetailsFeed, false, LoadFeedCallback.ResultType.REPLACE); } private Option<Fragment> getCurrentVisibleFragment() { if ( fragmentManager.getBackStackEntryCount() < 1 ) { return none(); } FragmentManager.BackStackEntry entry = fragmentManager.getBackStackEntryAt( fragmentManager.getBackStackEntryCount() - 1 ); Option<Fragment> result = option(fragmentManager.findFragmentByTag(entry.getName())); if ( isEmpty( result ) ){ LOG.debug("Could not find fragment with name " + entry.getName()); } return result; } @Override public boolean onSearchRequested() { Option<Boolean> result = getCurrentVisibleFragment().map( fragment -> { if ( fragment instanceof CatalogFragment ) { CatalogFragment catalogFragment = (CatalogFragment) fragment; catalogFragment.onSearchRequested(); return catalogFragment.supportsSearch(); } return false; }); return result.getOrElse(false); } @Override public void onBackPressed() { hideDetailsView(); super.onBackPressed(); } }