package info.varden.hauk.dialog; import android.app.ProgressDialog; import android.content.Context; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import java.util.regex.Matcher; import java.util.regex.Pattern; import info.varden.hauk.Constants; import info.varden.hauk.R; import info.varden.hauk.http.AdoptSharePacket; import info.varden.hauk.struct.Share; import info.varden.hauk.utils.Log; /** * A class that builds a dialog with two input boxes for adopting another share into a group share. * * @author Marius Lindvall */ public abstract class AdoptDialogBuilder implements CustomDialogBuilder { private final Context ctx; private final Share share; /** * Constructs the builder. * * @param ctx Android application context. * @param share The share that should be adopted into. */ protected AdoptDialogBuilder(Context ctx, Share share) { this.ctx = ctx; this.share = share; } /** * The text input box that will contain the sharing link entered or pasted by the user. */ private EditText dialogTxtShare; /** * The text input box that will contain the adopted user's nickname. */ private EditText dialogTxtNick; /** * Called if the share was successfully adopted. * * @param nick The nickname assigned to the share by the user. */ protected abstract void onSuccess(String nick); /** * Called if the share could not be adopted. * * @param ex An exception indicating the reason why the share could not be adopted. */ protected abstract void onFailure(Exception ex); /** * Called when the OK button is clicked in the dialog window. */ @Override public final void onPositive() { // Get the user data. String nick = this.dialogTxtNick.getText().toString().trim(); String adoptID = this.dialogTxtShare.getText().toString().trim(); Log.v("User initiated adoption with nick=%s, id=%s", nick, adoptID); //NON-NLS // Create a processing dialog, since we are interacting with an external server, which can // take some time. final ProgressDialog progress = new ProgressDialog(this.ctx); progress.setProgressStyle(ProgressDialog.STYLE_SPINNER); progress.setTitle(R.string.progress_adopt_title); progress.setMessage(String.format(this.ctx.getString(R.string.progress_adopt_body), nick)); progress.setIndeterminate(true); progress.setCancelable(false); progress.show(); // Send the HTTP request to try and adopt the share. new AdoptSharePacket(this.ctx, this.share, adoptID, nick) { @Override public void onSuccessfulAdoption(String nickname) { Log.i("Adoption was successful for nick=%s", nickname); //NON-NLS progress.dismiss(); AdoptDialogBuilder.this.onSuccess(nickname); } @Override protected void onFailure(Exception ex) { Log.w("Adoption failed", ex); //NON-NLS progress.dismiss(); AdoptDialogBuilder.this.onFailure(ex); } }.send(); } /** * Called when the Cancel button is clicked in the dialog window. */ @Override public final void onNegative() { Log.v("User aborted adoption"); //NON-NLS } /** * Creates a View that is rendered in the dialog window. * * @param ctx Android application context. * @return A View instance to render on the dialog. */ @Override public final View createView(Context ctx) { // TODO: Inflate this instead // Ensure input boxes fill the entire width of the dialog. TableRow.LayoutParams trParams = new TableRow.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT); trParams.weight = 1.0F; TableLayout layout = new TableLayout(ctx); TableRow shareRow = new TableRow(ctx); shareRow.setLayoutParams(trParams); TableRow nickRow = new TableRow(ctx); nickRow.setLayoutParams(trParams); TextView textShare = new TextView(ctx); textShare.setText(R.string.label_share_url); TextView textNick = new TextView(ctx); textNick.setText(R.string.label_nickname); this.dialogTxtShare = new EditText(ctx); this.dialogTxtShare.setInputType(InputType.TYPE_CLASS_TEXT); this.dialogTxtShare.setLayoutParams(trParams); this.dialogTxtShare.addTextChangedListener(new LinkIDMatchReplacementListener(this.dialogTxtShare)); this.dialogTxtNick = new EditText(ctx); this.dialogTxtNick.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME); this.dialogTxtNick.setLayoutParams(trParams); shareRow.addView(textShare); shareRow.addView(this.dialogTxtShare); nickRow.addView(textNick); nickRow.addView(this.dialogTxtNick); layout.addView(shareRow); layout.addView(nickRow); return layout; } /** * A watcher class that watches a text input box and replaces its contents with the * corresponding link ID if a view link is entered or pasted into the box by the user. */ private static final class LinkIDMatchReplacementListener implements TextWatcher { /** * The text input box that should be watched and updated. */ private final EditText inputBox; private LinkIDMatchReplacementListener(EditText inputBox) { this.inputBox = inputBox; } @Override public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { } @Override public void onTextChanged(CharSequence charSequence, int start, int before, int count) { // When the share URL text is changed, try to extract the share ID using regex. If // a match is found, replace the entire contents with the match. Matcher matcher = Pattern.compile(Constants.REGEX_ADOPT_ID_FROM_LINK).matcher(charSequence); if (matcher.find()) { Log.i("Found possible link ID %s in URL %s; replacing", matcher.group(1), charSequence); //NON-NLS this.inputBox.setText(matcher.group(1)); } } @Override public void afterTextChanged(Editable editable) { } } }