org.lol.reddit.activities.PostListingActivity.java Source code

Java tutorial

Introduction

Here is the source code for org.lol.reddit.activities.PostListingActivity.java

Source

/*******************************************************************************
 * 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.lol.reddit.activities;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.view.WindowManager;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import org.holoeverywhere.app.Activity;
import org.holoeverywhere.app.AlertDialog;
import org.holoeverywhere.preference.PreferenceManager;
import org.holoeverywhere.preference.SharedPreferences;
import org.holoeverywhere.widget.EditText;
import org.holoeverywhere.widget.LinearLayout;
import org.lol.reddit.R;
import org.lol.reddit.account.RedditAccount;
import org.lol.reddit.account.RedditAccountChangeListener;
import org.lol.reddit.account.RedditAccountManager;
import org.lol.reddit.common.General;
import org.lol.reddit.common.LinkHandler;
import org.lol.reddit.common.PrefsUtility;
import org.lol.reddit.fragments.PostListingFragment;
import org.lol.reddit.fragments.SessionListDialog;
import org.lol.reddit.listingcontrollers.PostListingController;
import org.lol.reddit.reddit.api.RedditSubredditSubscriptionManager;
import org.lol.reddit.reddit.prepared.RedditPreparedPost;
import org.lol.reddit.reddit.url.PostCommentListingURL;
import org.lol.reddit.reddit.url.PostListingURL;
import org.lol.reddit.reddit.url.RedditURLParser;
import org.lol.reddit.reddit.url.SearchPostListURL;
import org.lol.reddit.views.RedditPostView;

import java.util.UUID;

public class PostListingActivity extends RefreshableActivity
        implements RedditAccountChangeListener, RedditPostView.PostSelectionListener,
        SharedPreferences.OnSharedPreferenceChangeListener, OptionsMenuUtility.OptionsMenuPostsListener,
        SessionChangeListener, RedditSubredditSubscriptionManager.SubredditSubscriptionStateChangeListener {

    private PostListingFragment fragment;
    private PostListingController controller;

    private SharedPreferences sharedPreferences;

    public void onCreate(final Bundle savedInstanceState) {

        PrefsUtility.applyTheme(this);

        // TODO load from savedInstanceState

        getSupportActionBar().setHomeButtonEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        getWindow().setBackgroundDrawable(new ColorDrawable(getSupportActionBarContext()
                .obtainStyledAttributes(new int[] { R.attr.rrListBackgroundCol }).getColor(0, 0)));

        sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        sharedPreferences.registerOnSharedPreferenceChangeListener(this);

        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("'%s' is not a post listing URL!", url.generateJsonUri()));
            }

            controller = new PostListingController((PostListingURL) url);

            OptionsMenuUtility.fixActionBar(this, url.humanReadableName(this, false));

            super.onCreate(savedInstanceState);

            setContentView(R.layout.main_single);
            requestRefresh(RefreshableFragment.POSTS, false);

        } else {
            throw new RuntimeException("Nothing to show! (should load from bundle)"); // TODO
        }

        addSubscriptionListener();
    }

    @Override
    protected void onSaveInstanceState(final Bundle outState) {
        super.onSaveInstanceState(outState);
        // TODO save instance state
    }

    @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;

        OptionsMenuUtility.prepare(this, menu, false, true, false, controller.isSortable(), true,
                subredditSubscriptionState, subredditDescription != null && subredditDescription.length() > 0,
                false);

        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) {
        if (fragment != null)
            fragment.cancel();
        fragment = controller.get(force);
        final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.main_single_frame, fragment, "post_listing_fragment");
        transaction.commit();
    }

    public void onPostSelected(final RedditPreparedPost post) {
        LinkHandler.onLinkClicked(this, post.url, false, post.src);
    }

    public void onPostCommentsSelected(final RedditPreparedPost post) {
        LinkHandler.onLinkClicked(this, PostCommentListingURL.forPostId(post.idAlone).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(this);
    }

    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 PostListingController.Sort order) {
        controller.setSort(order);
        requestRefresh(RefreshableFragment.POSTS, false);
    }

    @Override
    public void onSearchPosts() {
        onSearchPosts(controller, this);
    }

    public static void onSearchPosts(final PostListingController controller, final Activity activity) {

        final AlertDialog.Builder alertBuilder = new AlertDialog.Builder(activity);
        final LinearLayout layout = (LinearLayout) activity.getLayoutInflater().inflate(R.layout.dialog_editbox);
        final EditText editText = (EditText) layout.findViewById(R.id.dialog_editbox_edittext);

        editText.requestFocus();

        alertBuilder.setView(layout);
        alertBuilder.setTitle(R.string.action_search);

        alertBuilder.setPositiveButton(R.string.action_search, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {

                final String query = editText.getText().toString().toLowerCase().trim();

                final SearchPostListURL url;

                if (controller != null && controller.isSubreddit()) {
                    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);
            }
        });

        alertBuilder.setNegativeButton(R.string.dialog_cancel, null);

        final AlertDialog alertDialog = alertBuilder.create();
        alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
        alertDialog.show();
    }

    @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("%s: %s", getString(R.string.sidebar_activity_title), fragment.getSubreddit().url));
        startActivityForResult(intent, 1);
    }

    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {

        if (PrefsUtility.isRestartRequired(this, key)) {
            requestRefresh(RefreshableFragment.RESTART, false);
        }

        if (PrefsUtility.isRefreshRequired(this, key)) {
            requestRefresh(RefreshableFragment.ALL, false);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    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();
            }
        });
    }
}