package com.airlocksoftware.hackernews.activity;
import org.apache.commons.lang3.StringUtils;
import android.util.Log;
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.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.webkit.URLUtil;
import android.widget.EditText;
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.SubmitLoader;
import com.airlocksoftware.hackernews.model.Page;
import com.airlocksoftware.hackernews.model.NewStoryResult;
import com.airlocksoftware.holo.actionbar.ActionBarButton;
import com.airlocksoftware.holo.actionbar.ActionBarButton.Priority;
import com.airlocksoftware.holo.utils.ViewUtils;
/**
* Activity for submitting stories to HN. It is exported in the manifest so that it can receive ACTION_SEND share
* Intents. Submission is performed in background by SubmitLoader.
**/
public class SubmitActivity extends SlideoutMenuActivity implements LoaderManager.LoaderCallbacks<NewStoryResult> {
private boolean mFromShareIntent = false;
private SendMode mSendMode = SendMode.EMPTY;
private String mTitleText, mSelfText, mUrlText;
private EditText mTitleEditText, mSelfEditText, mUrlEditText;
private ActionBarButton mSendButton, mCancelButton;
public enum SendMode {
EMPTY, SELF_TEXT, URL;
}
public static final String TAG = SubmitActivity.class.getSimpleName();
public static final String TITLE_STRING = SearchActivity.class.getSimpleName() + ".title";
public static final String SELF_STRING = SearchActivity.class.getSimpleName() + ".text";
public static final String URL_STRING = SearchActivity.class.getSimpleName() + ".url";
private OnClickListener mSendListener = new OnClickListener() {
@Override
public void onClick(View v) {
retrieveInputFromEditTexts();
// validate input
boolean validTitle = StringUtils.isNotBlank(mTitleText) && mTitleText.length() < 80;
boolean validSelfText = StringUtils.isNotBlank(mSelfText);
boolean validUrl = validateURL(mUrlText);
boolean oneOrTheOther = validSelfText != validUrl;
if (!validTitle) {
Toast.makeText(getApplicationContext(),
getString(R.string.submitting_title_too_long),
Toast.LENGTH_LONG).show();
} else if (!oneOrTheOther) {
Toast.makeText(getApplicationContext(),
getString(R.string.error_submitting),
Toast.LENGTH_LONG).show();
} else {
// input is valid, send via SubmitLoader
mSendButton.setVisibility(View.GONE);
mCancelButton.showProgress(true).onClick(null);
mSendMode = validSelfText ? SendMode.SELF_TEXT : SendMode.URL;
getSupportLoaderManager().restartLoader(0, null, SubmitActivity.this);
Toast.makeText(getApplicationContext(),
getString(R.string.submitting),
Toast.LENGTH_LONG).show();
}
}
};
private OnClickListener mCancelListener = new OnClickListener() {
@Override
public void onClick(View v) {
if (!mFromShareIntent) startActivity(new Intent(SubmitActivity.this, MainActivity.class));
finish();
}
};
private TextWatcher mEditWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
refreshEditTextEnabledState();
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
setContentView(R.layout.act_submit);
ViewUtils.fixBackgroundRepeat(findViewById(R.id.root_scroll));
retrieveBundles(savedState, getIntent().getExtras());
retrieveShareIntent(getIntent(), getIntent().getAction(), getIntent().getType());
UserPrefs userPrefs = new UserPrefs(this);
if (!userPrefs.isLoggedIn()) sendToLoginActivity();
super.setActiveMenuItem(R.id.submit_button);
setupActionBar();
findAndBindViews();
refreshEditTextEnabledState();
// startup loader (but it won't actually be run because we have nothing to submit yet)
getSupportLoaderManager().initLoader(0, null, SubmitActivity.this);
}
private void findAndBindViews() {
// find views
mTitleEditText = (EditText) findViewById(R.id.edit_title);
mSelfEditText = (EditText) findViewById(R.id.edit_selftext);
mUrlEditText = (EditText) findViewById(R.id.edit_url);
// set text
if (StringUtils.isNotBlank(mTitleText)) mTitleEditText.setText(mTitleText);
if (StringUtils.isNotBlank(mSelfText)) mSelfEditText.setText(mSelfText);
if (StringUtils.isNotBlank(mUrlText)) mUrlEditText.setText(mUrlText);
// attach text watchers
mSelfEditText.addTextChangedListener(mEditWatcher);
mUrlEditText.addTextChangedListener(mEditWatcher);
}
private void setupActionBar() {
getActionBarView().getController().setTitleText(getString(R.string.submit));
mSendButton = new ActionBarButton(this);
mSendButton.icon(R.drawable.ic_action_send)
.priority(Priority.HIGH)
.onClick(mSendListener)
.text(getString(R.string.submit));
getActionBarView().getController().addButton(mSendButton);
mCancelButton = new ActionBarButton(this);
mCancelButton.icon(R.drawable.ic_action_cancel)
.priority(Priority.HIGH)
.onClick(mCancelListener)
.text(getString(R.string.cancel));
getActionBarView().getController().addButton(mCancelButton);
}
private void sendToLoginActivity() {
Intent loginIntent = new Intent(this, LoginActivity.class);
loginIntent.putExtra(LoginActivity.POST_ACTION, PostAction.SUBMIT);
if (StringUtils.isNotBlank(mSelfText)) {
loginIntent.putExtra(LoginActivity.POST_SUB_TEXT, mSelfText);
} else if (StringUtils.isNotBlank(mUrlText)) {
loginIntent.putExtra(LoginActivity.POST_SUB_TEXT, mSelfText);
}
startActivity(loginIntent);
finish();
}
private void retrieveShareIntent(Intent intent, String action, String type) {
if (Intent.ACTION_SEND.equals(action) && type != null) {
if ("text/plain".equals(type)) {
mFromShareIntent = true;
String title = intent.getStringExtra(android.content.Intent.EXTRA_SUBJECT);
String text = intent.getStringExtra(android.content.Intent.EXTRA_TEXT);
if (StringUtils.isNotBlank(title)) mTitleText = title;
// check for url or text
if (StringUtils.isNotBlank(text)) {
if (validateURL(text)) {
mUrlText = text;
} else {
mSelfText = text;
}
}
}
}
}
private void retrieveBundles(Bundle savedState, Bundle extras) {
// restoring saved state
if (savedState != null) {
mTitleText = savedState.getString(TITLE_STRING);
mSelfText = savedState.getString(SELF_STRING);
mUrlText = savedState.getString(URL_STRING);
}
// getting intent extras - can overwrite savedState - is that correct?
if (extras != null) {
mTitleText = extras.getString(TITLE_STRING);
mSelfText = extras.getString(SELF_STRING);
mUrlText = extras.getString(URL_STRING);
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(TITLE_STRING, mTitleText);
outState.putString(SELF_STRING, mSelfText);
outState.putString(URL_STRING, mUrlText);
super.onSaveInstanceState(outState);
}
protected boolean validateURL(String url) {
return StringUtils.isNotBlank(url) && URLUtil.isValidUrl(url);
}
protected void refreshEditTextEnabledState() {
if (mSelfEditText.getText() != null && mSelfEditText.getText().length() > 0) {
mSelfEditText.setEnabled(true);
mUrlEditText.setEnabled(false);
} else if (mUrlEditText.getText() != null && mUrlEditText.getText().length() > 0) {
mSelfEditText.setEnabled(false);
mUrlEditText.setEnabled(true);
} else {
mSelfEditText.setEnabled(true);
mUrlEditText.setEnabled(true);
}
}
private void retrieveInputFromEditTexts() {
mTitleText = mTitleEditText.getText() == null ? "" : mTitleEditText.getText().toString();
mSelfText = mSelfEditText.getText() == null ? "" : mSelfEditText.getText().toString();
mUrlText = mUrlEditText.getText() == null ? "" : mUrlEditText.getText().toString();
}
// Loader callbacks
@Override
public Loader<NewStoryResult> onCreateLoader(int id, Bundle args) {
String content = null;
if (mSendMode == SendMode.SELF_TEXT) {
content = mSelfText;
} else if (mSendMode == SendMode.URL) {
content = mUrlText;
}
return new SubmitLoader(this, mSendMode, mTitleText, content);
}
@Override
public void onLoadFinished(Loader<NewStoryResult> loader, NewStoryResult result) {
switch (result) {
case SUCCESS:
Toast.makeText(getApplicationContext(),
getString(R.string.submitted),
Toast.LENGTH_LONG).show();
if (!mFromShareIntent) {
Intent intent = new Intent(SubmitActivity.this, MainActivity.class);
intent.putExtra(MainActivity.PAGE, Page.NEW);
startActivity(intent);
}
finish();
return;
case POST_DUPLICATE:
Toast.makeText(getApplicationContext(),
getString(R.string.error_post_duplicate),
Toast.LENGTH_LONG).show();
if (!mFromShareIntent) {
Intent intent = new Intent(SubmitActivity.this, MainActivity.class);
intent.putExtra(MainActivity.PAGE, Page.FRONT);
startActivity(intent);
}
finish();
return;
case POST_TOO_FAST:
Toast.makeText(getApplicationContext(),
getString(R.string.error_post_too_fast),
Toast.LENGTH_LONG).show();
break;
case FAILURE:
Toast.makeText(getApplicationContext(),
getString(R.string.error_loading),
Toast.LENGTH_LONG).show();
break;
default:
break;
}
mSendButton.setVisibility(View.VISIBLE);
mCancelButton.showProgress(false).onClick(mCancelListener);
}
@Override
public void onLoaderReset(Loader<NewStoryResult> loader) {
// no implementation necessary
}
// Static startup method
public static void startSubmitActivity(Context context, String submissionTitle, String submissionText) {
Intent intent = new Intent(context, SubmitActivity.class);
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, submissionTitle);
intent.putExtra(android.content.Intent.EXTRA_TEXT, submissionText);
context.startActivity(intent);
}
}