package com.airlocksoftware.hackernews.activity; import org.apache.commons.lang3.StringUtils; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.view.View; import android.view.View.OnClickListener; import android.widget.Toast; import com.airlocksoftware.hackernews.R; import com.airlocksoftware.hackernews.activity.LoginActivity.PostAction; import com.airlocksoftware.hackernews.data.UserPrefs; import com.airlocksoftware.hackernews.loader.ReplyLoader; import com.airlocksoftware.hackernews.model.Comment; import com.airlocksoftware.hackernews.model.Result; import com.airlocksoftware.hackernews.model.Story; import com.airlocksoftware.holo.actionbar.ActionBarButton; import com.airlocksoftware.holo.type.FontEdit; import com.airlocksoftware.holo.type.FontText; /** * Activity for replying to Comments or Stories (i.e. top-level comments). Uses ReplyLoader to send the reply in the * background. If the user is not logged in, pass them to the LoginActivity. **/ public class ReplyActivity extends BackActivity implements LoaderManager.LoaderCallbacks<Result> { // State private Story mStory; private Comment mComment; private String mReplyText; private boolean mReadyToSend = false; // Views FontText mParentUsername, mParentTitle, mParentComment, mReplyUsername; FontEdit mReplyComment; // Listeners private OnClickListener mSendListener = new OnClickListener() { @Override public void onClick(View v) { mReplyText = mReplyComment.getText() .toString(); if (StringUtils.isNotBlank(mReplyText)) { mReadyToSend = true; getSupportLoaderManager().restartLoader(0, null, ReplyActivity.this); } else { Toast.makeText(getApplicationContext(), getString(R.string.reply_is_blank), Toast.LENGTH_LONG) .show(); } } }; private OnClickListener mCancelListener = new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(ReplyActivity.this, "Reply canceled.", Toast.LENGTH_SHORT) .show(); finish(); } }; // Constants public static final String COMMENT = ReplyActivity.class.getSimpleName() + ".comment"; public static final String STORY = ReplyActivity.class.getSimpleName() + ".story"; public static final String REPLY_TEXT = ReplyActivity.class.getSimpleName() + ".replyText"; @Override public void onCreate(Bundle savedState) { super.onCreate(savedState); setContentView(R.layout.act_reply); findViews(); retrieveBundles(savedState, getIntent().getExtras()); retrieveUserPrefs(); setupActionBar(); bindViews(); // startup loader (but it won't really be run) getSupportLoaderManager().initLoader(0, null, ReplyActivity.this); } private void bindViews() { if (mReplyText != null) mReplyComment.setText(mReplyText); mReplyUsername.setText(new UserPrefs(this).getUsername()); if (mStory != null) { mParentTitle.setText(mStory.title); mParentUsername.setText(mStory.username); if (mStory.selfText != null) mParentComment.setText(mStory.selfText); else mParentComment.setVisibility(View.GONE); } else if (mComment != null) { mParentUsername.setText(mComment.username); mParentComment.setText(mComment.generateSpannedHtml()); mParentTitle.setVisibility(View.GONE); } else throw new RuntimeException("Neither a comment nor a story was passed to reply activity."); } private void setupActionBar() { getActionBarView().getController() .setTitleText(getString(R.string.reply)); ActionBarButton send = new ActionBarButton(this).icon(R.drawable.ic_action_send); ActionBarButton cancel = new ActionBarButton(this).icon(R.drawable.ic_action_cancel); send.text("Send") .setOnClickListener(mSendListener); cancel.text("Cancel") .setOnClickListener(mCancelListener); getActionBarView().getController() .addButton(send); getActionBarView().getController() .addButton(cancel); } /** Check UserPrefs for logged in state. **/ private void retrieveUserPrefs() { if (!new UserPrefs(this).isLoggedIn()) { // start LoginActivity with appropriate PostAction Intent intent = new Intent(this, LoginActivity.class); if (mComment != null) intent.putExtra(LoginActivity.POST_COMMENT, mComment); else if (mStory != null) intent.putExtra(LoginActivity.POST_STORY, mStory); intent.putExtra(LoginActivity.POST_ACTION, PostAction.REPLY); startActivity(intent); } } private void retrieveBundles(Bundle savedState, Bundle extras) { if (savedState != null) { mStory = (Story) savedState.getSerializable(STORY); mComment = (Comment) savedState.getSerializable(COMMENT); mReplyText = savedState.getString(REPLY_TEXT); } if (extras != null) { mStory = (Story) extras.getSerializable(STORY); mComment = (Comment) extras.getSerializable(COMMENT); } } private void findViews() { mParentUsername = (FontText) findViewById(R.id.txt_parent_username); mParentTitle = (FontText) findViewById(R.id.txt_parent_title); mParentComment = (FontText) findViewById(R.id.txt_parent_comment); mReplyUsername = (FontText) findViewById(R.id.txt_reply_username); mReplyComment = (FontEdit) findViewById(R.id.edit_reply_comment); } @Override public void onSaveInstanceState(Bundle outState) { mReplyText = mReplyComment.getText() .toString(); if (mStory != null) outState.putSerializable(STORY, mStory); if (mComment != null) outState.putSerializable(COMMENT, mComment); if (StringUtils.isNotBlank(mReplyText)) outState.putString(REPLY_TEXT, mReplyText); super.onSaveInstanceState(outState); } @Override public Loader<Result> onCreateLoader(int id, Bundle args) { // setup replyId long replyId = -1; if (mStory != null) replyId = mStory.storyId; else if (mComment != null) replyId = mComment.commentId; if (mReadyToSend) return new ReplyLoader(this, replyId, mReplyText); else return new ReplyLoader(this); // no data to send reply with } @Override public void onLoadFinished(Loader<Result> loader, Result result) { switch (result) { case FAILURE: Toast.makeText(this, getString(R.string.reply_no_connection), Toast.LENGTH_LONG) .show(); break; case SUCCESS: Toast.makeText(this, getString(R.string.reply_sent), Toast.LENGTH_SHORT) .show(); finish(); break; default: // no data was passed to loader aka we weren't ready to send data (do nothing) break; } } @Override public void onLoaderReset(Loader<Result> loader) { // No implementation necessary } public static void startCommentReplyActivity(Context context, Comment comment) { Intent intent = new Intent(context, ReplyActivity.class); intent.putExtra(COMMENT, comment); context.startActivity(intent); } public static void startStoryReplyActivity(Context context, Story story) { Intent intent = new Intent(context, ReplyActivity.class); intent.putExtra(ReplyActivity.STORY, story); context.startActivity(intent); } }