package org.wordpress.android.ui.accounts;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.wordpress.android.R;
import org.wordpress.android.WordPress;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.fluxc.Dispatcher;
import org.wordpress.android.fluxc.generated.SiteActionBuilder;
import org.wordpress.android.fluxc.model.SiteModel;
import org.wordpress.android.fluxc.network.rest.wpcom.site.DomainSuggestionResponse;
import org.wordpress.android.fluxc.store.SiteStore;
import org.wordpress.android.fluxc.store.SiteStore.NewSiteErrorType;
import org.wordpress.android.fluxc.store.SiteStore.NewSitePayload;
import org.wordpress.android.fluxc.store.SiteStore.OnNewSiteCreated;
import org.wordpress.android.fluxc.store.SiteStore.OnSiteChanged;
import org.wordpress.android.fluxc.store.SiteStore.OnSuggestedDomains;
import org.wordpress.android.fluxc.store.SiteStore.SiteVisibility;
import org.wordpress.android.fluxc.store.SiteStore.SuggestDomainsPayload;
import org.wordpress.android.ui.main.SitePickerActivity;
import org.wordpress.android.util.AlertUtils;
import org.wordpress.android.util.AppLog;
import org.wordpress.android.util.AppLog.T;
import org.wordpress.android.util.EditTextUtils;
import org.wordpress.android.util.LanguageUtils;
import org.wordpress.android.util.ToastUtils;
import org.wordpress.android.util.ToastUtils.Duration;
import org.wordpress.android.widgets.WPTextView;
import javax.inject.Inject;
public class NewBlogFragment extends AbstractFragment implements TextWatcher {
private AutoCompleteTextView mSiteUrlTextField;
private EditText mSiteTitleTextField;
private ArrayAdapter<String> mSiteUrlSuggestionAdapter;
private WPTextView mSignupButton;
private WPTextView mProgressTextSignIn;
private WPTextView mCancelButton;
private RelativeLayout mProgressBarSignIn;
private boolean mSignoutOnCancelMode;
private long mNewSiteRemoteId;
@Inject Dispatcher mDispatcher;
@Inject SiteStore mSiteStore;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((WordPress) getActivity().getApplication()).component().inject(this);
mSiteUrlSuggestionAdapter = new ArrayAdapter<>(getActivity(), R.layout.domain_suggestion_dropdown);
}
@Override
public void onStart() {
super.onStart();
mDispatcher.register(this);
}
@Override
public void onStop() {
mDispatcher.unregister(this);
super.onStop();
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
checkIfFieldsFilled();
}
public void setSignoutOnCancelMode(boolean mode) {
mSignoutOnCancelMode = mode;
mCancelButton.setVisibility(View.VISIBLE);
}
public boolean isSignoutOnCancelMode() {
return mSignoutOnCancelMode;
}
public void onBackPressed() {
signoutAndFinish();
}
protected void onDoneAction() {
validateAndCreateUserAndBlog();
}
private void signoutAndFinish() {
if (mSignoutOnCancelMode) {
((WordPress) getActivity().getApplication()).wordPressComSignOut();
getActivity().setResult(Activity.RESULT_CANCELED);
getActivity().finish();
}
}
private boolean fieldsFilled() {
return EditTextUtils.getText(mSiteUrlTextField).trim().length() > 0
&& EditTextUtils.getText(mSiteTitleTextField).trim().length() > 0;
}
protected void startProgress(String message) {
mProgressBarSignIn.setVisibility(View.VISIBLE);
mProgressTextSignIn.setVisibility(View.VISIBLE);
mSignupButton.setVisibility(View.GONE);
mProgressBarSignIn.setEnabled(false);
mProgressTextSignIn.setText(message);
mSiteTitleTextField.setEnabled(false);
mSiteUrlTextField.setEnabled(false);
}
protected void updateProgress(String message) {
mProgressTextSignIn.setText(message);
}
protected void endProgress() {
mProgressBarSignIn.setVisibility(View.GONE);
mProgressTextSignIn.setVisibility(View.GONE);
mSignupButton.setVisibility(View.VISIBLE);
mSiteTitleTextField.setEnabled(true);
mSiteUrlTextField.setEnabled(true);
}
private void showSiteUrlError(String message) {
mSiteUrlTextField.setError(message);
mSiteUrlTextField.requestFocus();
}
private void showSiteTitleError(String message) {
mSiteTitleTextField.setError(message);
mSiteTitleTextField.requestFocus();
}
protected boolean showError(NewSiteErrorType newSiteError, String message) {
if (!isAdded()) {
return false;
}
switch (newSiteError) {
case SITE_TITLE_INVALID:
showSiteTitleError(message);
return true;
default:
showSiteUrlError(message);
return true;
}
}
protected boolean isUserDataValid() {
final String siteTitle = EditTextUtils.getText(mSiteTitleTextField).trim();
final String siteUrl = EditTextUtils.getText(mSiteUrlTextField).trim();
boolean retValue = true;
if (siteTitle.equals("")) {
mSiteTitleTextField.setError(getString(R.string.required_field));
mSiteTitleTextField.requestFocus();
retValue = false;
}
if (siteUrl.equals("")) {
mSiteUrlTextField.setError(getString(R.string.required_field));
mSiteUrlTextField.requestFocus();
retValue = false;
}
return retValue;
}
private String titleToUrl(String siteUrl) {
return siteUrl.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
}
private void validateAndCreateUserAndBlog() {
if (mSystemService.getActiveNetworkInfo() == null) {
AlertUtils.showAlert(getActivity(), R.string.no_network_title, R.string.no_network_message);
return;
}
if (!isUserDataValid()) {
return;
}
// prevent double tapping of the "done" btn in keyboard for those clients that don't dismiss the keyboard.
// Samsung S4 for example
if (View.VISIBLE == mProgressBarSignIn.getVisibility()) {
return;
}
startProgress(getString(R.string.creating_your_site));
final String siteUrl = EditTextUtils.getText(mSiteUrlTextField).trim();
final String siteTitle = EditTextUtils.getText(mSiteTitleTextField).trim();
final String language = LanguageUtils.getPatchedCurrentDeviceLanguage(getActivity());
NewSitePayload newSitePayload = new NewSitePayload(siteUrl, siteTitle, language, SiteVisibility.PUBLIC, false);
mDispatcher.dispatch(SiteActionBuilder.newCreateNewSiteAction(newSitePayload));
AppLog.i(T.NUX, "User tries to create a new site, title: " + siteTitle + ", URL: " + siteUrl);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout containing a title and body text.
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.create_blog_fragment, container, false);
mSignupButton = (WPTextView) rootView.findViewById(R.id.signup_button);
mSignupButton.setOnClickListener(mSignupClickListener);
mSignupButton.setEnabled(false);
mCancelButton = (WPTextView) rootView.findViewById(R.id.cancel_button);
mCancelButton.setOnClickListener(mCancelClickListener);
mProgressTextSignIn = (WPTextView) rootView.findViewById(R.id.nux_sign_in_progress_text);
mProgressBarSignIn = (RelativeLayout) rootView.findViewById(R.id.nux_sign_in_progress_bar);
mSiteUrlTextField = (AutoCompleteTextView) rootView.findViewById(R.id.site_url);
mSiteUrlTextField.setAdapter(mSiteUrlSuggestionAdapter);
mSiteUrlTextField.setOnEditorActionListener(mEditorAction);
mSiteUrlTextField.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
checkIfFieldsFilled();
}
@Override
public void afterTextChanged(Editable editable) {
lowerCaseEditable(editable);
}
});
mSiteUrlTextField.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus && !mSiteUrlSuggestionAdapter.isEmpty()) {
mSiteUrlTextField.showDropDown();
}
}
});
mSiteTitleTextField = (EditText) rootView.findViewById(R.id.site_title);
mSiteTitleTextField.addTextChangedListener(this);
mSiteTitleTextField.addTextChangedListener(mSiteTitleWatcher);
mSiteTitleTextField.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
getDomainSuggestionsFromTitle();
}
}
});
return rootView;
}
private void checkIfFieldsFilled() {
if (fieldsFilled()) {
mSignupButton.setEnabled(true);
} else {
mSignupButton.setEnabled(false);
}
}
private final OnClickListener mSignupClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
validateAndCreateUserAndBlog();
}
};
private final OnClickListener mCancelClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
signoutAndFinish();
}
};
private final TextWatcher mSiteTitleWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
mSiteUrlSuggestionAdapter.clear();
mSiteUrlSuggestionAdapter.notifyDataSetChanged();
}
};
private void getDomainSuggestionsFromTitle() {
String title = EditTextUtils.getText(mSiteTitleTextField);
if (!TextUtils.isEmpty(title)) {
SuggestDomainsPayload payload = new SuggestDomainsPayload(title, true, false, 5);
mDispatcher.dispatch(SiteActionBuilder.newSuggestDomainsAction(payload));
}
}
private final TextView.OnEditorActionListener mEditorAction = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
return onDoneEvent(actionId, event);
}
};
// OnChanged events
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNewSiteCreated(OnNewSiteCreated event) {
AppLog.i(T.NUX, event.toString());
if (event.isError()) {
endProgress();
showError(event.error.type, event.error.message);
return;
}
AnalyticsTracker.track(AnalyticsTracker.Stat.CREATED_SITE);
mNewSiteRemoteId = event.newSiteRemoteId;
// We can't get all the site informations from the new site endpoint, so we have to fetch the site list.
mDispatcher.dispatch(SiteActionBuilder.newFetchSitesAction());
}
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSiteChanged(OnSiteChanged event) {
AppLog.i(T.NUX, event.toString());
// Sites updated, we can finish this.
if (getActivity() == null) {
return;
}
endProgress();
if (event.isError()) {
// Site has been created but there was a error while fetching the sites. Can happen if we get
// a response including a broken Jetpack site. We can continue and check if the newly created
// site has been fetched.
AppLog.e(T.NUX, event.error.type.toString());
}
SiteModel site = mSiteStore.getSiteBySiteId(mNewSiteRemoteId);
Intent intent = new Intent();
if (site != null) {
intent.putExtra(SitePickerActivity.KEY_LOCAL_ID, site.getId());
} else {
ToastUtils.showToast(getActivity(), R.string.error_fetch_site_after_creation, Duration.LONG);
}
getActivity().setResult(Activity.RESULT_OK, intent);
getActivity().finish();
}
@SuppressWarnings("unused")
@Subscribe(threadMode = ThreadMode.MAIN)
public void onSuggestedDomains(OnSuggestedDomains event) {
if (!isAdded() || event.isError()) {
return;
}
mSiteUrlSuggestionAdapter.clear();
for (DomainSuggestionResponse suggestion : event.suggestions) {
// Only add free suggestions ending by .wordpress.com
if (suggestion.is_free && !TextUtils.isEmpty(suggestion.domain_name)
&& suggestion.domain_name.endsWith(".wordpress.com")) {
mSiteUrlSuggestionAdapter.add(suggestion.domain_name.replace(".wordpress.com", ""));
}
}
if (!mSiteUrlSuggestionAdapter.isEmpty() && mSiteUrlTextField.hasFocus()) {
mSiteUrlTextField.showDropDown();
}
}
}