com.lloydtorres.stately.issues.IssueDecisionActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.lloydtorres.stately.issues.IssueDecisionActivity.java

Source

/**
 * Copyright 2016 Lloyd Torres
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lloydtorres.stately.issues;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog;
import android.view.View;

import com.android.volley.NetworkError;
import com.android.volley.NoConnectionError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.lloydtorres.stately.R;
import com.lloydtorres.stately.core.RefreshviewActivity;
import com.lloydtorres.stately.dto.Issue;
import com.lloydtorres.stately.dto.IssueOption;
import com.lloydtorres.stately.dto.Nation;
import com.lloydtorres.stately.helpers.RaraHelper;
import com.lloydtorres.stately.helpers.SparkleHelper;
import com.lloydtorres.stately.helpers.network.DashHelper;
import com.lloydtorres.stately.helpers.network.NSStringRequest;
import com.lloydtorres.stately.settings.SettingsActivity;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Created by Lloyd on 2016-01-28.
 * This activity displays options for a particular issue.
 */
public class IssueDecisionActivity extends RefreshviewActivity {
    // Keys for Intent data
    public static final String ISSUE_DATA = "issueData";
    public static final String NATION_DATA = "nationData";
    public static final int DISMISSED = -1;
    private static final String LEGISLATION_PASSED = "LEGISLATION PASSED";
    private static final String STORY_SO_FAR = "The Story So Far";
    private static final String NOT_AVAILABLE = "Issue Not Available";

    private Issue issue;
    private Nation mNation;

    private boolean isInProgress;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        removePaddingTop();

        isInProgress = false;
        // Either get data from intent or restore state
        if (getIntent() != null) {
            issue = getIntent().getParcelableExtra(ISSUE_DATA);
            mNation = getIntent().getParcelableExtra(NATION_DATA);
        }
        if (savedInstanceState != null) {
            issue = savedInstanceState.getParcelable(ISSUE_DATA);
            mNation = savedInstanceState.getParcelable(NATION_DATA);
        }

        getSupportActionBar().setTitle(
                String.format(Locale.US, getString(R.string.issue_activity_title), mNation.name, issue.id));

        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                queryIssueInfo();
            }
        });
    }

    /**
     * Call to start querying and activate SwipeFreshLayout
     */
    private void startQueryIssueInfo() {
        // hack to get swiperefreshlayout to show initially while loading
        mSwipeRefreshLayout.post(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(true);
                queryIssueInfo();
            }
        });
    }

    /**
     * Query information on the current issue from the actual NationStates site
     */
    private void queryIssueInfo() {
        String targetURL = String.format(Locale.US, IssueOption.QUERY, issue.id);

        NSStringRequest stringRequest = new NSStringRequest(getApplicationContext(), Request.Method.GET, targetURL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Document d = Jsoup.parse(response, SparkleHelper.BASE_URI);
                        processIssueInfo(mView, d);
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        SparkleHelper.logError(error.toString());
                        mSwipeRefreshLayout.setRefreshing(false);
                        if (error instanceof TimeoutError || error instanceof NoConnectionError
                                || error instanceof NetworkError) {
                            SparkleHelper.makeSnackbar(mView, getString(R.string.login_error_no_internet));
                        } else {
                            SparkleHelper.makeSnackbar(mView, getString(R.string.login_error_generic));
                        }
                    }
                });

        if (!DashHelper.getInstance(this).addRequest(stringRequest)) {
            mSwipeRefreshLayout.setRefreshing(false);
            SparkleHelper.makeSnackbar(mView, getString(R.string.rate_limit_error));
        }
    }

    /**
     * Process the received page into the Issue and its IssueOptions
     * @param v Activity view
     * @param d Document received from NationStates
     */
    private void processIssueInfo(View v, Document d) {
        // First check if the issue is still available
        if (d.text().contains(NOT_AVAILABLE)) {
            mSwipeRefreshLayout.setRefreshing(false);
            SparkleHelper.makeSnackbar(v,
                    String.format(Locale.US, getString(R.string.issue_unavailable), mNation.name));
            return;
        }

        Element issueInfoContainer = d.select("div#dilemma").first();

        if (issueInfoContainer == null) {
            // safety check
            mSwipeRefreshLayout.setRefreshing(false);
            SparkleHelper.makeSnackbar(v, getString(R.string.login_error_parsing));
            return;
        }

        Elements issueInfoRaw = issueInfoContainer.children();

        String issueText = issueInfoRaw.select("p").first().text();
        // If this is an issue chain, grab the second paragraph instead
        if (d.select("div.dilemmachain").first() != null) {
            issueText = issueInfoRaw.select("p").get(1).text();
            if (d.text().contains(STORY_SO_FAR)) {
                issueText = issueText + "<br><br>" + issueInfoRaw.select("p").get(2).text();
            }
        }
        issue.content = issueText;

        issue.options = new ArrayList<IssueOption>();

        Element optionHolderMain = issueInfoRaw.select("ol.diloptions").first();
        if (optionHolderMain != null) {
            Elements optionsHolder = optionHolderMain.select("li");

            int i = 0;
            for (Element option : optionsHolder) {
                IssueOption issueOption = new IssueOption();
                issueOption.index = i++;

                Element button = option.select("button").first();
                if (button != null) {
                    issueOption.header = button.attr("name");
                } else {
                    issueOption.header = IssueOption.SELECTED_HEADER;
                }

                Element optionContentHolder = option.select("p").first();
                if (optionContentHolder == null) {
                    // safety check
                    mSwipeRefreshLayout.setRefreshing(false);
                    SparkleHelper.makeSnackbar(v, getString(R.string.login_error_parsing));
                    return;
                }

                issueOption.content = optionContentHolder.text();
                issue.options.add(issueOption);
            }
        }

        IssueOption dismissOption = new IssueOption();
        dismissOption.index = -1;
        dismissOption.header = IssueOption.DISMISS_HEADER;
        dismissOption.content = "";
        issue.options.add(dismissOption);

        setRecyclerAdapter(issue);
        mSwipeRefreshLayout.setRefreshing(false);
        mSwipeRefreshLayout.setEnabled(false);
    }

    private void setRecyclerAdapter(Issue issue) {
        if (mRecyclerAdapter == null) {
            mRecyclerAdapter = new IssueDecisionRecyclerAdapter(this, issue);
            mRecyclerView.setAdapter(mRecyclerAdapter);
        } else {
            ((IssueDecisionRecyclerAdapter) mRecyclerAdapter).setIssue(issue);
        }
    }

    /**
     * Helper to confirm the position selected by the user.
     * @param option The option selected.
     */
    public void setAdoptPosition(final IssueOption option) {
        if (isInProgress) {
            SparkleHelper.makeSnackbar(mView, getString(R.string.multiple_request_error));
            return;
        }

        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this, RaraHelper.getThemeMaterialDialog(this));
        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startPostAdoptPosition(option);
                dialog.dismiss();
            }
        };

        if (SettingsActivity.getConfirmIssueDecisionSetting(this)) {
            dialogBuilder.setNegativeButton(getString(R.string.explore_negative), null);

            switch (option.index) {
            case DISMISSED:
                dialogBuilder.setTitle(getString(R.string.issue_option_confirm_dismiss))
                        .setPositiveButton(getString(R.string.issue_option_dismiss), dialogClickListener);
                break;
            default:
                dialogBuilder
                        .setTitle(String.format(Locale.US, getString(R.string.issue_option_confirm_adopt),
                                option.index + 1))
                        .setPositiveButton(getString(R.string.issue_option_adopt), dialogClickListener);
                break;
            }

            dialogBuilder.show();
        } else {
            startPostAdoptPosition(option);
        }
    }

    private void startPostAdoptPosition(final IssueOption option) {
        mSwipeRefreshLayout.post(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(true);
                postAdoptPosition(option);
            }
        });
    }

    /**
     * Send the position selected by the user back to the server.
     * @param option The option selected.
     */
    public void postAdoptPosition(final IssueOption option) {
        isInProgress = true;
        String targetURL = String.format(Locale.US, IssueOption.POST_QUERY, issue.id);

        NSStringRequest stringRequest = new NSStringRequest(getApplicationContext(), Request.Method.POST, targetURL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        isInProgress = false;
                        if (!IssueOption.DISMISS_HEADER.equals(option.header)) {
                            if (response.contains(LEGISLATION_PASSED)) {
                                Intent issueResultsActivity = new Intent(IssueDecisionActivity.this,
                                        IssueResultsActivity.class);
                                issueResultsActivity.putExtra(IssueResultsActivity.RESPONSE_DATA, response);
                                issueResultsActivity.putExtra(IssueResultsActivity.OPTION_DATA, option);
                                issueResultsActivity.putExtra(IssueResultsActivity.NATION_DATA, mNation);
                                startActivity(issueResultsActivity);
                                finish();
                            } else {
                                SparkleHelper.makeSnackbar(mView, getString(R.string.login_error_generic));
                            }
                        } else {
                            finish();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        SparkleHelper.logError(error.toString());
                        mSwipeRefreshLayout.setRefreshing(false);
                        isInProgress = false;
                        if (error instanceof TimeoutError || error instanceof NoConnectionError
                                || error instanceof NetworkError) {
                            SparkleHelper.makeSnackbar(mView, getString(R.string.login_error_no_internet));
                        } else {
                            SparkleHelper.makeSnackbar(mView, getString(R.string.login_error_generic));
                        }
                    }
                });

        Map<String, String> params = new HashMap<String, String>();
        params.put(option.header, "1");
        stringRequest.setParams(params);

        if (!DashHelper.getInstance(this).addRequest(stringRequest)) {
            mSwipeRefreshLayout.setRefreshing(false);
            isInProgress = false;
            SparkleHelper.makeSnackbar(mView, getString(R.string.rate_limit_error));
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        if (issue.options == null) {
            startQueryIssueInfo();
        } else {
            setRecyclerAdapter(issue);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
        // Save state
        super.onSaveInstanceState(savedInstanceState);
        if (issue != null) {
            savedInstanceState.putParcelable(ISSUE_DATA, issue);
        }
        if (mNation != null) {
            savedInstanceState.putParcelable(NATION_DATA, mNation);
        }
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Restore state
        super.onRestoreInstanceState(savedInstanceState);
        if (savedInstanceState != null) {
            if (issue == null) {
                issue = savedInstanceState.getParcelable(ISSUE_DATA);
            }
            if (mNation == null) {
                mNation = savedInstanceState.getParcelable(NATION_DATA);
            }
        }
    }
}