improvements to smsinviter dialog: add explanatory empty text, dialog

that warns when non-mobile number being added, always check
newly-added number, etc.
This commit is contained in:
Eric House 2012-04-11 18:54:38 -07:00
parent 0c241cf207
commit 31659bc514
5 changed files with 156 additions and 92 deletions

View file

@ -21,30 +21,19 @@
android:padding="8dp" android:padding="8dp"
/> />
<LinearLayout android:orientation="horizontal" <TextView android:id="@android:id/empty"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
> android:text="@string/empty_sms_inviter"
<EditText android:id="@+id/phone_edit" android:padding="20dp"
android:layout_height="wrap_content" />
<Button android:id="@+id/button_invite"
android:text="@string/button_invite"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:scrollHorizontally="true"
android:phoneNumber="true"
android:singleLine="true"
android:maxLength="15"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="1"
android:hint="@string/manual_number_hint"
/>
<ImageButton android:id="@+id/manual_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_add" android:layout_marginBottom="10dip"
android:gravity="right"
android:layout_weight="0"
android:visibility="invisible"
/> />
</LinearLayout>
<LinearLayout android:orientation="horizontal" <LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent" android:layout_width="fill_parent"
@ -52,22 +41,20 @@
> >
<Button android:id="@+id/button_add" <Button android:id="@+id/button_add"
android:text="@string/button_sms_add" android:text="@string/button_sms_add"
android:layout_width="fill_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1"
/> />
<Button android:id="@+id/button_clear" <Button android:id="@+id/button_clear"
android:text="@string/bt_pick_clear_button" android:text="@string/bt_pick_clear_button"
android:layout_width="fill_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton android:id="@+id/manual_add_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_input_add"
android:clickable="false"
/> />
</LinearLayout> </LinearLayout>
<Button android:id="@+id/button_invite"
android:text="@string/button_invite"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout> </LinearLayout>

View file

@ -1848,7 +1848,7 @@
<string name="newgame_enable_bt">Turn Bluetooth on</string> <string name="newgame_enable_bt">Turn Bluetooth on</string>
<string name="bt_pick_rescan_button">Rescan</string> <string name="bt_pick_rescan_button">Rescan</string>
<string name="bt_pick_clear_button">Remove selected</string> <string name="bt_pick_clear_button">Remove checked</string>
<string name="bt_pick_title">Opponent devices</string> <string name="bt_pick_title">Opponent devices</string>
<string name="scan_progress">Scanning for Crosswords on paired devices</string> <string name="scan_progress">Scanning for Crosswords on paired devices</string>
@ -1879,7 +1879,7 @@
%2$d seconds.</string> %2$d seconds.</string>
<string name="bt_failf">Bluetooth sends to %1$s have failed too many <string name="bt_failf">Bluetooth sends to %1$s have failed too many
times. Re-open the game to try again.</string> times. Re-open the game to try again.</string>
<string name="button_invite">Invite selected</string> <string name="button_invite">Invite checked</string>
<string name="btname_label">New Bluetooth game name</string> <string name="btname_label">New Bluetooth game name</string>
<string name="smsname_label">New SMS game name</string> <string name="smsname_label">New SMS game name</string>
@ -1904,11 +1904,18 @@
<string name="new_smsmove_title">New move via SMS</string> <string name="new_smsmove_title">New move via SMS</string>
<string name="button_sms_add">Import contact</string> <string name="button_sms_add">Import contact</string>
<string name="invite_sms_descf">Please select the %d phone number[s] <string name="invite_sms_descf">Please check the %d phone
you want to invite to this game. Use the Import contact button if number[s] you want to invite to your new game, then tap \"Invite
you don\'t see the number you want.</string> checked\".</string>
<string name="manual_number_hint">Enter manually</string> <string name="manual_number_hint">Enter manually</string>
<string name="manual_owner_name">(Entered manually)</string> <string name="manual_owner_name">(Entered manually)</string>
<string name="sms_nomobile">Contact has no mobile number.</string>
<string name="sms_nomobilef">Contact for %s has no mobile number.</string> <string name="warn_nomobilef">The number %1$s for %2$s is not
marked as mobile.</string>
<string name="button_use">Use anyway</string>
<string name="empty_sms_inviter">Phone list is empty. Use the
\"Import contact\" button to add people you want to
invite, the + button to enter numbers.</string>
<string name="get_sms_number">Enter phone number:</string>
</resources> </resources>

View file

@ -21,9 +21,10 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.content.Context; import android.content.Context;
import android.text.method.KeyListener;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import junit.framework.Assert; import junit.framework.Assert;
@ -43,6 +44,12 @@ public class GameNamer extends LinearLayout {
view.setText( label ); view.setText( label );
} }
public void setKeyListener( KeyListener lstnr )
{
EditText view = (EditText)findViewById( R.id.name_edit );
view.setKeyListener( lstnr );
}
public void setLabel( int id ) public void setLabel( int id )
{ {
setLabel( m_context.getString( id ) ); setLabel( m_context.getString( id ) );

View file

@ -26,15 +26,16 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.os.Handler;
import junit.framework.Assert; import junit.framework.Assert;
@ -54,6 +55,9 @@ abstract class InviteActivity extends XWListActivity
int button_clear, int desc_id, int desc_strf ) int button_clear, int desc_id, int desc_strf )
{ {
super.onCreate( savedInstanceState ); super.onCreate( savedInstanceState );
requestWindowFeature( Window.FEATURE_NO_TITLE );
setContentView( view_id ); setContentView( view_id );
Intent intent = getIntent(); Intent intent = getIntent();

View file

@ -21,7 +21,10 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
@ -29,12 +32,12 @@ import android.os.Bundle;
import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds; import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.text.method.DialerKeyListener;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CompoundButton; import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ListView; import android.widget.ListView;
import java.util.ArrayList; import java.util.ArrayList;
@ -45,14 +48,19 @@ import junit.framework.Assert;
import org.eehouse.android.xw4.jni.CommonPrefs; import org.eehouse.android.xw4.jni.CommonPrefs;
public class SMSInviteActivity extends InviteActivity implements TextWatcher { public class SMSInviteActivity extends InviteActivity {
private static final int GET_CONTACT = 1; private static final int GET_CONTACT = 1;
private static final int CONFIRM_NON_MOBILE = DlgDelegate.DIALOG_LAST + 1;
private static final int GET_NUMBER = DlgDelegate.DIALOG_LAST + 2;
private static final String SAVE_NAME = "SAVE_NAME";
private static final String SAVE_NUMBER = "SAVE_NUMBER";
private ArrayList<PhoneRec> m_phoneRecs; private ArrayList<PhoneRec> m_phoneRecs;
private SMSPhonesAdapter m_adapter; private SMSPhonesAdapter m_adapter;
private EditText m_manualField;
private ImageButton m_addButton; private ImageButton m_addButton;
private String m_pendingName;
private String m_pendingNumber;
@Override @Override
protected void onCreate( Bundle savedInstanceState ) protected void onCreate( Bundle savedInstanceState )
@ -61,23 +69,13 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
R.id.button_invite, R.id.button_add, R.id.button_invite, R.id.button_add,
R.id.button_clear, R.id.invite_desc, R.id.button_clear, R.id.invite_desc,
R.string.invite_sms_descf ); R.string.invite_sms_descf );
getBundledData( savedInstanceState );
m_manualField = (EditText)findViewById( R.id.phone_edit );
m_manualField.addTextChangedListener( this );
m_addButton = (ImageButton)findViewById( R.id.manual_add_button ); m_addButton = (ImageButton)findViewById( R.id.manual_add_button );
m_addButton.setOnClickListener( new View.OnClickListener() { m_addButton.setOnClickListener( new View.OnClickListener() {
public void onClick( View view ) public void onClick( View view )
{ {
String number = m_manualField.getText().toString(); showDialog( GET_NUMBER );
if ( 0 < number.length() ) {
m_manualField.setText("");
PhoneRec rec =
new PhoneRec( getString( R.string.manual_owner_name ),
number );
m_phoneRecs.add( rec );
saveState();
rebuildList();
}
} }
} ); } );
@ -86,6 +84,22 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
tryEnable(); tryEnable();
} }
@Override
protected void onSaveInstanceState( Bundle outState )
{
super.onSaveInstanceState( outState );
outState.putString( SAVE_NAME, m_pendingName );
outState.putString( SAVE_NUMBER, m_pendingNumber );
}
private void getBundledData( Bundle bundle )
{
if ( null != bundle ) {
m_pendingName = bundle.getString( SAVE_NAME );
m_pendingNumber = bundle.getString( SAVE_NUMBER );
}
}
@Override @Override
protected void onActivityResult( int requestCode, int resultCode, protected void onActivityResult( int requestCode, int resultCode,
Intent data ) Intent data )
@ -100,6 +114,56 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
} }
} }
@Override
protected Dialog onCreateDialog( int id )
{
Dialog dialog = super.onCreateDialog( id );
if ( null == dialog ) {
DialogInterface.OnClickListener lstnr;
switch( id ) {
case CONFIRM_NON_MOBILE:
lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
addChecked( new PhoneRec( m_pendingName,
m_pendingNumber ) );
saveAndRebuild();
}
};
String msg = Utils.format( this, R.string.warn_nomobilef,
m_pendingNumber, m_pendingName );
dialog = new AlertDialog.Builder( this )
.setMessage( msg )
.setPositiveButton( R.string.button_ok, null )
.setNegativeButton( R.string.button_use, lstnr )
.create();
break;
case GET_NUMBER:
final GameNamer namerView =
(GameNamer)Utils.inflate( this, R.layout.rename_game );
namerView.setLabel( R.string.get_sms_number );
namerView.setKeyListener(DialerKeyListener.getInstance());
lstnr = new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dlg, int item ) {
String number = namerView.getName();
String name =
getString( R.string.manual_owner_name );
PhoneRec rec = new PhoneRec( name, number );
addChecked( rec );
saveAndRebuild();
}
};
dialog = new AlertDialog.Builder( this )
.setNegativeButton( R.string.button_cancel, null )
.setPositiveButton( R.string.button_ok, lstnr )
.setView( namerView )
.create();
break;
}
Utils.setRemoveOnDismiss( this, dialog, id );
}
return dialog;
}
protected void scan() protected void scan()
{ {
Intent intent = new Intent( Intent.ACTION_PICK, Intent intent = new Intent( Intent.ACTION_PICK,
@ -116,8 +180,7 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
m_phoneRecs.remove( ii ); m_phoneRecs.remove( ii );
} }
} }
saveState(); saveAndRebuild();
rebuildList();
} }
protected String[] listSelected() protected String[] listSelected()
@ -171,20 +234,15 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
name = cursor.getString( cursor.getColumnIndex( Phone.DISPLAY_NAME)); name = cursor.getString( cursor.getColumnIndex( Phone.DISPLAY_NAME));
String number = String number =
cursor.getString( cursor.getColumnIndex( Phone.NUMBER ) ); cursor.getString( cursor.getColumnIndex( Phone.NUMBER ) );
int type = cursor.getInt( cursor.getColumnIndex( Phone.TYPE ) );
if ( Phone.TYPE_MOBILE == type && 0 < number.length() ) { int type = cursor.getInt( cursor.getColumnIndex( Phone.TYPE ) );
m_phoneRecs.add( new PhoneRec( name, number ) ); if ( Phone.TYPE_MOBILE == type ) {
} addChecked( new PhoneRec( name, number ) );
if ( len_before != m_phoneRecs.size() ) { saveAndRebuild();
saveState();
rebuildList();
} else { } else {
int resid = null != name && 0 < name.length() m_pendingName = name;
? R.string.sms_nomobilef m_pendingNumber = number;
: R.string.sms_nomobile; showDialog( CONFIRM_NON_MOBILE );
String msg = Utils.format( this, resid, name );
showOKOnlyDialog( msg );
} }
cursor.close(); cursor.close();
} }
@ -215,7 +273,7 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
} }
} }
private void saveState() private void saveAndRebuild()
{ {
String[] names = new String[m_phoneRecs.size()]; String[] names = new String[m_phoneRecs.size()];
String[] phones = new String[m_phoneRecs.size()]; String[] phones = new String[m_phoneRecs.size()];
@ -227,6 +285,19 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
} }
CommonPrefs.setSMSNames( this, names ); CommonPrefs.setSMSNames( this, names );
CommonPrefs.setSMSPhones( this, phones ); CommonPrefs.setSMSPhones( this, phones );
rebuildList();
}
private void addChecked( PhoneRec rec )
{
Iterator<PhoneRec> iter = m_phoneRecs.iterator();
while ( iter.hasNext() ) {
iter.next().m_checked = false;
}
rec.m_checked = true;
m_phoneRecs.add( rec );
} }
private class PhoneRec { private class PhoneRec {
@ -234,10 +305,15 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
public String m_name; public String m_name;
public boolean m_checked; public boolean m_checked;
public PhoneRec( String name, String phone ) public PhoneRec( String name, String phone )
{
this( name, phone, false );
}
public PhoneRec( String name, String phone, boolean checked )
{ {
m_name = name; m_name = name;
m_phone = phone; m_phone = phone;
m_checked = false; m_checked = checked;
} }
} }
@ -290,21 +366,4 @@ public class SMSInviteActivity extends InviteActivity implements TextWatcher {
return checked; return checked;
} }
} }
// TextWatcher interface
public void afterTextChanged( Editable s )
{
m_addButton.setVisibility( 0 == s.length()
? View.INVISIBLE : View.VISIBLE );
}
public void beforeTextChanged( CharSequence s, int start,
int count, int after )
{
}
public void onTextChanged( CharSequence s, int start,
int before, int count )
{
}
} }