/******************************************************************************* * This file is part of RedReader. * * RedReader 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. * * RedReader 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 RedReader. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.quantumbadger.redreader.activities; import android.content.Intent; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.View; import org.quantumbadger.redreader.R; import org.quantumbadger.redreader.account.RedditAccount; import org.quantumbadger.redreader.account.RedditAccountChangeListener; import org.quantumbadger.redreader.account.RedditAccountManager; import org.quantumbadger.redreader.common.DialogUtils; import org.quantumbadger.redreader.common.General; import org.quantumbadger.redreader.common.LinkHandler; import org.quantumbadger.redreader.common.PrefsUtility; import org.quantumbadger.redreader.fragments.PostListingFragment; import org.quantumbadger.redreader.fragments.SessionListDialog; import org.quantumbadger.redreader.listingcontrollers.PostListingController; import org.quantumbadger.redreader.reddit.PostSort; import org.quantumbadger.redreader.reddit.api.RedditSubredditSubscriptionManager; import org.quantumbadger.redreader.reddit.prepared.RedditPreparedPost; import org.quantumbadger.redreader.reddit.things.RedditSubreddit; import org.quantumbadger.redreader.reddit.url.PostCommentListingURL; import org.quantumbadger.redreader.reddit.url.PostListingURL; import org.quantumbadger.redreader.reddit.url.RedditURLParser; import org.quantumbadger.redreader.reddit.url.SearchPostListURL; import org.quantumbadger.redreader.views.RedditPostView; import java.util.Locale; import java.util.UUID; public class PostListingActivity extends RefreshableActivity implements RedditAccountChangeListener, RedditPostView.PostSelectionListener, OptionsMenuUtility.OptionsMenuPostsListener, SessionChangeListener, RedditSubredditSubscriptionManager.SubredditSubscriptionStateChangeListener { private static final String SAVEDSTATE_SESSION = "pla_session"; private static final String SAVEDSTATE_SORT = "pla_sort"; private static final String SAVEDSTATE_FRAGMENT = "pla_fragment"; private PostListingFragment fragment; private PostListingController controller; public void onCreate(final Bundle savedInstanceState) { PrefsUtility.applyTheme(this); super.onCreate(savedInstanceState); getWindow().setBackgroundDrawable(new ColorDrawable(obtainStyledAttributes(new int[] {R.attr.rrListBackgroundCol}).getColor(0,0))); RedditAccountManager.getInstance(this).addUpdateListener(this); if(getIntent() != null) { final Intent intent = getIntent(); final RedditURLParser.RedditURL url = RedditURLParser.parseProbablePostListing(intent.getData()); if(!(url instanceof PostListingURL)) { throw new RuntimeException(String.format(Locale.US, "'%s' is not a post listing URL!", url.generateJsonUri())); } controller = new PostListingController((PostListingURL)url, this); Bundle fragmentSavedInstanceState = null; if(savedInstanceState != null) { if(savedInstanceState.containsKey(SAVEDSTATE_SESSION)) { controller.setSession(UUID.fromString(savedInstanceState.getString(SAVEDSTATE_SESSION))); } if(savedInstanceState.containsKey(SAVEDSTATE_SORT)) { controller.setSort(PostSort.valueOf( savedInstanceState.getString(SAVEDSTATE_SORT))); } if(savedInstanceState.containsKey(SAVEDSTATE_FRAGMENT)) { fragmentSavedInstanceState = savedInstanceState.getBundle(SAVEDSTATE_FRAGMENT); } } setTitle(url.humanReadableName(this, false)); setBaseActivityContentView(R.layout.main_single); doRefresh(RefreshableFragment.POSTS, false, fragmentSavedInstanceState); } else { throw new RuntimeException("Nothing to show!"); } addSubscriptionListener(); } @Override protected void onSaveInstanceState(final Bundle outState) { super.onSaveInstanceState(outState); final UUID session = controller.getSession(); if(session != null) { outState.putString(SAVEDSTATE_SESSION, session.toString()); } final PostSort sort = controller.getSort(); if(sort != null) { outState.putString(SAVEDSTATE_SORT, sort.name()); } if(fragment != null) { outState.putBundle(SAVEDSTATE_FRAGMENT, fragment.onSaveInstanceState()); } } @Override public boolean onCreateOptionsMenu(final Menu menu) { final RedditAccount user = RedditAccountManager.getInstance(this).getDefaultAccount(); final RedditSubredditSubscriptionManager.SubredditSubscriptionState subredditSubscriptionState; final RedditSubredditSubscriptionManager subredditSubscriptionManager = RedditSubredditSubscriptionManager.getSingleton(this, user); if(!user.isAnonymous() && controller.isSubreddit() && subredditSubscriptionManager.areSubscriptionsReady() && fragment != null && fragment.getSubreddit() != null) { subredditSubscriptionState = subredditSubscriptionManager.getSubscriptionState(controller.subredditCanonicalName()); } else { subredditSubscriptionState = null; } final String subredditDescription = fragment != null && fragment.getSubreddit() != null ? fragment.getSubreddit().description_html : null; Boolean subredditPinState = null; Boolean subredditBlockedState = null; if(controller.isSubreddit() && fragment != null && fragment.getSubreddit() != null) { try { subredditPinState = PrefsUtility.pref_pinned_subreddits_check( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); subredditBlockedState = PrefsUtility.pref_blocked_subreddits_check( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); } catch(RedditSubreddit.InvalidSubredditNameException e) { subredditPinState = null; subredditBlockedState = null; } } OptionsMenuUtility.prepare( this, menu, false, true, false, controller.isSearchResults(), controller.isUserPostListing(), false, controller.isSortable(), true, subredditSubscriptionState, subredditDescription != null && subredditDescription.length() > 0, false, subredditPinState, subredditBlockedState); return true; } private void addSubscriptionListener() { RedditSubredditSubscriptionManager .getSingleton(this, RedditAccountManager.getInstance(this).getDefaultAccount()) .addListener(this); } public void onRedditAccountChanged() { addSubscriptionListener(); postInvalidateOptionsMenu(); requestRefresh(RefreshableFragment.ALL, false); } @Override protected void doRefresh(final RefreshableFragment which, final boolean force, final Bundle savedInstanceState) { if(fragment != null) fragment.cancel(); fragment = controller.get(this, force, savedInstanceState); final View view = fragment.getView(); setBaseActivityContentView(view); General.setLayoutMatchParent(view); } public void onPostSelected(final RedditPreparedPost post) { LinkHandler.onLinkClicked(this, post.src.getUrl(), false, post.src.getSrc()); } public void onPostCommentsSelected(final RedditPreparedPost post) { LinkHandler.onLinkClicked(this, PostCommentListingURL.forPostId(post.src.getIdAlone()).toString(), false); } public void onRefreshPosts() { controller.setSession(null); requestRefresh(RefreshableFragment.POSTS, true); } public void onPastPosts() { final SessionListDialog sessionListDialog = SessionListDialog.newInstance(controller.getUri(), controller.getSession(), SessionChangeType.POSTS); sessionListDialog.show(getSupportFragmentManager(), "SessionListDialog"); } public void onSubmitPost() { final Intent intent = new Intent(this, PostSubmitActivity.class); if(controller.isSubreddit()) { intent.putExtra("subreddit", controller.subredditCanonicalName()); } startActivity(intent); } public void onSortSelected(final PostSort order) { controller.setSort(order); requestRefresh(RefreshableFragment.POSTS, false); } @Override public void onSearchPosts() { onSearchPosts(controller, this); } public static void onSearchPosts(final PostListingController controller, final AppCompatActivity activity) { DialogUtils.showSearchDialog(activity, new DialogUtils.OnSearchListener() { @Override public void onSearch(@Nullable String query) { if (query == null) return; final SearchPostListURL url; if(controller != null && (controller.isSubreddit() || controller.isSubredditSearchResults())) { url = SearchPostListURL.build(controller.subredditCanonicalName(), query); } else { url = SearchPostListURL.build(null, query); } final Intent intent = new Intent(activity, PostListingActivity.class); intent.setData(url.generateJsonUri()); activity.startActivity(intent); } }); } @Override public void onSubscribe() { fragment.onSubscribe(); } @Override public void onUnsubscribe() { fragment.onUnsubscribe(); } @Override public void onSidebar() { final Intent intent = new Intent(this, HtmlViewActivity.class); intent.putExtra("html", fragment.getSubreddit().getSidebarHtml(PrefsUtility.isNightMode(this))); intent.putExtra("title", String.format(Locale.US, "%s: %s", getString(R.string.sidebar_activity_title), fragment.getSubreddit().url)); startActivityForResult(intent, 1); } @Override public void onPin() { if(fragment == null) return; try { PrefsUtility.pref_pinned_subreddits_add( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); } catch(RedditSubreddit.InvalidSubredditNameException e) { throw new RuntimeException(e); } invalidateOptionsMenu(); } @Override public void onUnpin() { if(fragment == null) return; try { PrefsUtility.pref_pinned_subreddits_remove( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); } catch(RedditSubreddit.InvalidSubredditNameException e) { throw new RuntimeException(e); } invalidateOptionsMenu(); } @Override public void onBlock() { if(fragment == null) return; try { PrefsUtility.pref_blocked_subreddits_add( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); } catch(RedditSubreddit.InvalidSubredditNameException e) { throw new RuntimeException(e); } invalidateOptionsMenu(); } @Override public void onUnblock() { if(fragment == null) return; try { PrefsUtility.pref_blocked_subreddits_remove( this, PreferenceManager.getDefaultSharedPreferences(this), fragment.getSubreddit().getCanonicalName()); } catch(RedditSubreddit.InvalidSubredditNameException e) { throw new RuntimeException(e); } invalidateOptionsMenu(); } public void onSessionSelected(UUID session, SessionChangeType type) { controller.setSession(session); requestRefresh(RefreshableFragment.POSTS, false); } public void onSessionRefreshSelected(SessionChangeType type) { onRefreshPosts(); } public void onSessionChanged(UUID session, SessionChangeType type, long timestamp) { controller.setSession(session); } @Override public void onBackPressed() { if(General.onBackPressed()) super.onBackPressed(); } @Override public void onSubredditSubscriptionListUpdated(RedditSubredditSubscriptionManager subredditSubscriptionManager) { postInvalidateOptionsMenu(); } @Override public void onSubredditSubscriptionAttempted(RedditSubredditSubscriptionManager subredditSubscriptionManager) { postInvalidateOptionsMenu(); } @Override public void onSubredditUnsubscriptionAttempted(RedditSubredditSubscriptionManager subredditSubscriptionManager) { postInvalidateOptionsMenu(); } private void postInvalidateOptionsMenu() { runOnUiThread(new Runnable() { @Override public void run() { invalidateOptionsMenu(); } }); } }