provide choice to invite known players

Add second type of option to the current list of "InviteMeans", so you
can configure a game then skip sending email if the player's address is
known.
This commit is contained in:
Eric House 2020-09-22 07:53:19 -07:00
parent fc05612b74
commit 8fa92ad00e
4 changed files with 186 additions and 93 deletions

View file

@ -531,7 +531,7 @@ public class BoardDelegate extends DelegateBase
if ( state.summary.hasRematchInfo() ) {
tryRematchInvites( true );
} else if ( state.summary.hasInviteInfo() ) {
tryOtherInvites( true );
tryOtherInvites();
} else {
callInviteChoices( sentInfo[0] );
}
@ -1240,6 +1240,11 @@ public class BoardDelegate extends DelegateBase
showArchiveNA( false );
break;
case LAUNCH_INVITE_ACTION:
CommsAddrRec addr = (CommsAddrRec)params[0];
tryOtherInvites( addr );
break;
case ENABLE_NBS_DO:
post( new Runnable() {
@Override
@ -1773,7 +1778,7 @@ public class BoardDelegate extends DelegateBase
if ( m_summary.hasRematchInfo() ) {
skipDismiss = !tryRematchInvites( false );
} else if ( m_summary.hasInviteInfo() ) {
skipDismiss = !tryOtherInvites( false );
skipDismiss = !tryOtherInvites();
} else if ( !m_haveInvited ) {
m_haveInvited = true;
showInviteAlertIf();
@ -2775,7 +2780,7 @@ public class BoardDelegate extends DelegateBase
if ( 0 < m_mySIS.nMissing && m_summary.hasRematchInfo() ) {
tryRematchInvites( false );
} else if ( 0 < m_mySIS.nMissing && m_summary.hasInviteInfo() ) {
tryOtherInvites( false );
tryOtherInvites();
} else if ( null != m_missingDevs ) {
Assert.assertNotNull( m_missingMeans );
String gameName = GameUtils.getName( m_activity, m_rowid );
@ -3196,43 +3201,48 @@ public class BoardDelegate extends DelegateBase
return force;
}
private boolean tryOtherInvites( boolean force )
private boolean tryOtherInvites()
{
boolean result = true;
boolean result = false;
Assert.assertNotNull( m_summary );
Assert.assertNotNull( m_gi );
String str64 = m_summary.getStringExtra( GameSummary.EXTRA_REMATCH_ADDR );
try {
CommsAddrRec addr = (CommsAddrRec)Utils.string64ToSerializable( str64 );
NetLaunchInfo nli = nliForMe();
CommsConnTypeSet conTypes = addr.conTypes;
for ( CommsConnType typ : conTypes ) {
switch ( typ ) {
case COMMS_CONN_MQTT:
MQTTUtils.inviteRemote( m_activity, addr.mqtt_devID, nli );
recordInviteSent( InviteMeans.MQTT, addr.mqtt_devID );
break;
case COMMS_CONN_BT:
BTService.inviteRemote( m_activity, addr.bt_btAddr, nli );
recordInviteSent( InviteMeans.BLUETOOTH, addr.bt_btAddr );
break;
result = tryOtherInvites( addr );
} catch ( Exception ex ) {
Log.ex( TAG, ex );
Assert.failDbg();
}
return result;
}
private boolean tryOtherInvites( CommsAddrRec addr )
{
boolean result = true;
NetLaunchInfo nli = nliForMe();
CommsConnTypeSet conTypes = addr.conTypes;
for ( CommsConnType typ : conTypes ) {
switch ( typ ) {
case COMMS_CONN_MQTT:
MQTTUtils.inviteRemote( m_activity, addr.mqtt_devID, nli );
recordInviteSent( InviteMeans.MQTT, addr.mqtt_devID );
break;
case COMMS_CONN_BT:
BTService.inviteRemote( m_activity, addr.bt_btAddr, nli );
recordInviteSent( InviteMeans.BLUETOOTH, addr.bt_btAddr );
break;
// case COMMS_CONN_RELAY:
// RelayService.inviteRemote( m_activity, m_jniGamePtr, 0, value, nli );
// recordInviteSent( InviteMeans.RELAY );
// break;
case COMMS_CONN_SMS:
sendNBSInviteIf( addr.sms_phone, nli, true );
recordInviteSent( InviteMeans.SMS_DATA, addr.sms_phone );
break;
case COMMS_CONN_SMS:
sendNBSInviteIf( addr.sms_phone, nli, true );
recordInviteSent( InviteMeans.SMS_DATA, addr.sms_phone );
break;
default:
Log.d( TAG, "not inviting using addr type %s", typ );
}
default:
Log.d( TAG, "not inviting using addr type %s", typ );
}
} catch ( Exception ex ) {
Log.ex( TAG, ex );
Assert.failDbg();
result = false;
}
return result;
}

View file

@ -1,7 +1,6 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDebug"; -*- */
/*
* Copyright 2017 - 2020 by Eric House (xwords@eehouse.org). All rights
* reserved.
* Copyright 2017 - 2020 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -25,6 +24,7 @@ import android.content.Context;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface;
import android.widget.Button;
import android.widget.RadioGroup;
import java.util.ArrayList;
import java.util.List;
@ -33,8 +33,12 @@ import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
import org.eehouse.android.xw4.DlgDelegate.Action;
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
import org.eehouse.android.xw4.Perms23.Perm;
import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.XwJNI;
import org.eehouse.android.xw4.loc.LocUtils;
public class InviteChoicesAlert extends DlgDelegateAlert {
public class InviteChoicesAlert extends DlgDelegateAlert
implements InviteView.ItemClicked {
public static InviteChoicesAlert newInstance( DlgState state )
{
@ -49,7 +53,7 @@ public class InviteChoicesAlert extends DlgDelegateAlert {
public void populateBuilder( final Context context, final DlgState state,
AlertDialog.Builder builder )
{
final ArrayList<InviteMeans> means = new ArrayList<>();
ArrayList<InviteMeans> means = new ArrayList<>();
InviteMeans lastMeans = null;
Object[] params = state.getParams();
if ( null != params
@ -80,78 +84,53 @@ public class InviteChoicesAlert extends DlgDelegateAlert {
}
means.add( InviteMeans.CLIPBOARD );
String[] items = new String[means.size()];
final int[] sel = { -1 };
for ( int ii = 0; ii < items.length; ++ii ) {
InviteMeans oneMeans = means.get(ii);
items[ii] = getString( oneMeans.getUserDescID() );
if ( lastMeans == oneMeans ) {
sel[0] = ii;
int lastSelMeans = -1;
if ( null != lastMeans ) {
for ( int ii = 0; ii < means.size(); ++ii ) {
if ( lastMeans == means.get(ii) ) {
lastSelMeans = ii;
break;
}
}
}
OnClickListener selChanged = new OnClickListener() {
public void onClick( DialogInterface dlg, int pos ) {
XWActivity activity = (XWActivity)getActivity();
sel[0] = pos;
switch ( means.get(pos) ) {
case SMS_USER:
activity
.makeNotAgainBuilder( R.string.sms_invite_flakey,
R.string.key_na_sms_invite_flakey )
.show();
break;
case CLIPBOARD:
String msg =
getString( R.string.not_again_clip_expl_fmt,
getString(R.string.slmenu_copy_sel) );
activity
.makeNotAgainBuilder(msg, R.string.key_na_clip_expl)
.show();
break;
case SMS_DATA:
if ( !Perms23.havePermissions( activity, Perm.SEND_SMS, Perm.RECEIVE_SMS )
&& Perm.SEND_SMS.isBanned(activity) ) {
activity
.makeOkOnlyBuilder( R.string.sms_banned_ok_only )
.setActionPair( Action.PERMS_BANNED_INFO,
R.string.button_more_info )
.show();
} else if ( ! XWPrefs.getNBSEnabled( context ) ) {
activity
.makeConfirmThenBuilder( R.string.warn_sms_disabled,
Action.ENABLE_NBS_ASK )
.setPosButton( R.string.button_enable_sms )
.setNegButton( R.string.button_later )
.show();
}
break;
}
Button button = ((AlertDialog)dlg)
.getButton( AlertDialog.BUTTON_POSITIVE );
button.setEnabled( true );
}
};
final InviteView inviteView = (InviteView)LocUtils
.inflate( context, R.layout.invite_view );
final OnClickListener okClicked = new OnClickListener() {
@Override
public void onClick( DialogInterface dlg, int pos ) {
Assert.assertTrue( Action.SKIP_CALLBACK != state.m_action );
int indx = sel[0];
if ( 0 <= indx ) {
Object choice = inviteView.getChoice();
if ( null != choice ) {
XWActivity activity = (XWActivity)context;
activity.inviteChoiceMade( state.m_action,
means.get(indx),
state.getParams() );
if ( choice instanceof InviteMeans ) {
InviteMeans means = (InviteMeans)choice;
activity.inviteChoiceMade( state.m_action,
means, state.getParams() );
} else if ( choice instanceof String ) {
String player = (String)choice;
CommsAddrRec addr = XwJNI.kplr_getAddr( player );
XWActivity xwact = (XWActivity)context;
Object[] params = { addr };
xwact.onPosButton( state.m_action, params );
} else {
Assert.failDbg();
}
}
}
};
builder.setTitle( R.string.invite_choice_title )
.setSingleChoiceItems( items, sel[0], selChanged )
builder
.setTitle( R.string.invite_choice_title )
.setView( inviteView )
.setPositiveButton( android.R.string.ok, okClicked )
.setNegativeButton( android.R.string.cancel, null );
.setNegativeButton( android.R.string.cancel, null )
;
String[] players = XwJNI.kplr_getPlayers();
inviteView.setChoices( means, lastSelMeans, players )
.setCallbacks( this );
if ( BuildConfig.DEBUG ) {
OnClickListener ocl = new OnClickListener() {
@Override
@ -167,4 +146,46 @@ public class InviteChoicesAlert extends DlgDelegateAlert {
builder.setNeutralButton( R.string.ok_with_robots, ocl );
}
}
@Override
public void meansClicked( InviteMeans means )
{
DlgDelegate.Builder builder = null;
XWActivity activity = (XWActivity)getActivity();
switch ( means ) {
case SMS_USER:
builder =activity
.makeNotAgainBuilder( R.string.sms_invite_flakey,
R.string.key_na_sms_invite_flakey );
break;
case CLIPBOARD:
String msg =
getString( R.string.not_again_clip_expl_fmt,
getString(R.string.slmenu_copy_sel) );
builder = activity
.makeNotAgainBuilder(msg, R.string.key_na_clip_expl);
break;
case SMS_DATA:
if ( !Perms23.havePermissions( activity, Perm.SEND_SMS, Perm.RECEIVE_SMS )
&& Perm.SEND_SMS.isBanned(activity) ) {
builder = activity
.makeOkOnlyBuilder( R.string.sms_banned_ok_only )
.setActionPair( Action.PERMS_BANNED_INFO,
R.string.button_more_info )
;
} else if ( ! XWPrefs.getNBSEnabled( getContext() ) ) {
builder = activity
.makeConfirmThenBuilder( R.string.warn_sms_disabled,
Action.ENABLE_NBS_ASK )
.setPosButton( R.string.button_enable_sms )
.setNegButton( R.string.button_later )
;
}
break;
}
if ( null != builder ) {
builder.show();
}
}
}

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<org.eehouse.android.xw4.InviteView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
>
<!-- Parent is a ScrollView, so I'm the only child -->
<LinearLayout android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RadioGroup android:id="@+id/group_tab"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
>
<RadioButton android:id="@+id/radio_who"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/radio_who"
/>
<RadioButton android:id="@+id/radio_how"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/radio_how"
/>
</RadioGroup>
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RadioGroup android:id="@+id/group_who"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<RadioGroup android:id="@+id/group_how"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView android:id="@+id/who_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/invite_who_empty_expl"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
</FrameLayout>
</LinearLayout>
</org.eehouse.android.xw4.InviteView>

View file

@ -1008,6 +1008,7 @@
<string name="newgame_invite">Invite now</string>
<string name="newgame_invite_more">More info</string>
<string name="newgame_drop_relay">Drop Relay</string>
<!-- EXPLAIN ME -->
<!-- <string name="bt_disabled">Bluetooth is not available. This may -->
<!-- mean that your device doesn\'t support it, or that it\'s been -->
@ -1022,7 +1023,13 @@
<string name="invite_choice_nfc">NFC (“Android beaming”)</string>
<string name="invite_choice_relay">Internet/Relay</string>
<string name="invite_choice_p2p">Wifi Direct</string>
<string name="invite_choice_title">Inviting players: How?</string>
<string name="invite_choice_title">Inviting players</string>
<!-- Radio button in invite choices dialog for list of previous opponents -->
<string name="radio_who">Who?</string>
<!-- Text shown only when there are not any previous opponents to invite -->
<string name="invite_who_empty_expl">empty expl</string>
<!-- Radio button in invite choices dialog for list ways to send an invitation -->
<string name="radio_how">How?</string>
<!-- Button, on DEBUG builds only, causes invitee players to be robots -->
<string name="ok_with_robots">OK (robots)</string>
<!-- <string name="sms_or_email">Send invitation using SMS (texting) or -->