mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
invite alert changes
Create new class that owns the alert. Let it decide whether to post, remove, etc. Seems to work, but I've removed some of the "reinvite" options I'm not sure were helpful anyway. To be considered...
This commit is contained in:
parent
105f93f3ab
commit
f3bb0c99a9
12 changed files with 311 additions and 365 deletions
|
@ -81,7 +81,7 @@ public class BoardDelegate extends DelegateBase
|
|||
implements TransportProcs.TPMsgHandler, View.OnClickListener,
|
||||
DwnldDelegate.DownloadFinishedListener,
|
||||
ConnStatusHandler.ConnStatusCBacks,
|
||||
Wrapper.Procs {
|
||||
Wrapper.Procs, InvitesNeededAlert.Callbacks {
|
||||
private static final String TAG = BoardDelegate.class.getSimpleName();
|
||||
|
||||
private static final int SCREEN_ON_TIME = 10 * 60 * 1000; // 10 mins
|
||||
|
@ -124,11 +124,9 @@ public class BoardDelegate extends DelegateBase
|
|||
private boolean m_startSkipped;
|
||||
private JNIThread.GameStateInfo m_gsi;
|
||||
|
||||
private int m_nGuestDevs = -1;
|
||||
private boolean m_showedReInvite;
|
||||
private boolean m_overNotShown;
|
||||
private boolean m_dropRelayOnDismiss;
|
||||
private DBAlert m_inviteAlert;
|
||||
private boolean m_haveStartedShowing;
|
||||
|
||||
private Wrapper mNFCWrapper;
|
||||
|
@ -163,12 +161,11 @@ public class BoardDelegate extends DelegateBase
|
|||
private static enum StartAlertOrder { NBS_PERMS, NO_MEANS, INVITE, DONE, };
|
||||
|
||||
private static class MySIS implements Serializable {
|
||||
MySIS() { nMissing = -1; }
|
||||
String toastStr;
|
||||
String[] words;
|
||||
String getDict;
|
||||
int nMissing;
|
||||
int nAlerts;
|
||||
int nMissing = -1;
|
||||
int nGuestDevs;
|
||||
boolean inTrade;
|
||||
StartAlertOrder mAlertOrder = StartAlertOrder.values()[0];
|
||||
}
|
||||
|
@ -177,7 +174,8 @@ public class BoardDelegate extends DelegateBase
|
|||
private boolean alertOrderAt( StartAlertOrder ord )
|
||||
{
|
||||
boolean result = m_mySIS.mAlertOrder == ord;
|
||||
// Log.d( TAG, "alertOrderAt(%s) => %b", ord, result );
|
||||
// Log.d( TAG, "alertOrderAt(%s) => %b (at %s)", ord, result,
|
||||
// m_mySIS.mAlertOrder );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -414,10 +412,8 @@ public class BoardDelegate extends DelegateBase
|
|||
.setNegativeButton( R.string.button_no, null )
|
||||
.create();
|
||||
break;
|
||||
case DLG_INVITE: {
|
||||
InviteAlertState state = (InviteAlertState)params[0];
|
||||
dialog = makeInviteDialog( alert, state );
|
||||
}
|
||||
case DLG_INVITE:
|
||||
dialog = InvitesNeededAlert.make( this, alert, params );
|
||||
break;
|
||||
|
||||
case ENABLE_NFC:
|
||||
|
@ -447,160 +443,6 @@ public class BoardDelegate extends DelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
private static class InviteAlertState implements Serializable {
|
||||
GameSummary summary;
|
||||
CurGameInfo gi;
|
||||
boolean relayMissing;
|
||||
CommsConnTypeSet connTypes;
|
||||
long rowid;
|
||||
int nMissing;
|
||||
}
|
||||
|
||||
private Dialog makeInviteDialog( final DBAlert alert,
|
||||
final InviteAlertState state )
|
||||
{
|
||||
Dialog dialog = null;
|
||||
final Activity activity = alert.getActivity();
|
||||
if ( null != activity ) {
|
||||
final SentInvitesInfo[] sentInfo = { null };
|
||||
String message;
|
||||
int titleID;
|
||||
boolean showInviteButton = true;
|
||||
boolean showNeutButton = false;
|
||||
|
||||
int buttonTxt = R.string.newgame_invite;
|
||||
|
||||
if ( state.relayMissing ) {
|
||||
titleID = R.string.seeking_relay;
|
||||
// If relay is only means, don't allow at all
|
||||
boolean relayOnly = 1 >= state.connTypes.size();
|
||||
showInviteButton = !relayOnly;
|
||||
message = activity.getString( R.string.no_relay_conn );
|
||||
if ( NetStateCache.netAvail( activity )
|
||||
&& NetStateCache.onWifi() ) {
|
||||
message += LocUtils.getString( activity, R.string.wifi_warning );
|
||||
}
|
||||
if ( !relayOnly ) {
|
||||
CommsConnTypeSet without = (CommsConnTypeSet)
|
||||
state.connTypes.clone();
|
||||
without.remove( CommsConnType.COMMS_CONN_RELAY );
|
||||
message += "\n\n"
|
||||
+ LocUtils.getString( activity,
|
||||
R.string.drop_relay_warning_fmt,
|
||||
without.toString( activity, true ) );
|
||||
buttonTxt = R.string.newgame_drop_relay;
|
||||
}
|
||||
} else {
|
||||
sentInfo[0] = DBUtils.getInvitesFor( activity, state.rowid );
|
||||
int nSent = sentInfo[0].getMinPlayerCount();
|
||||
boolean invitesSent = nSent >= state.nMissing;
|
||||
if ( invitesSent ) {
|
||||
m_showedReInvite = true;
|
||||
if ( state.summary.hasRematchInfo() ) {
|
||||
titleID = R.string.waiting_rematch_title;
|
||||
message = LocUtils.getString( activity, R.string.rematch_msg );
|
||||
} else {
|
||||
titleID = R.string.waiting_invite_title;
|
||||
message = LocUtils
|
||||
.getQuantityString( activity, R.plurals.invite_sent_fmt,
|
||||
nSent, nSent, state.nMissing );
|
||||
}
|
||||
buttonTxt = R.string.button_reinvite;
|
||||
showNeutButton = true;
|
||||
} else if ( DeviceRole.SERVER_ISCLIENT == state.gi.serverRole ) {
|
||||
Assert.assertFalse( state.summary.hasRematchInfo() );
|
||||
message = LocUtils.getString( activity, R.string.invited_msg );
|
||||
titleID = R.string.waiting_title;
|
||||
showInviteButton = false;
|
||||
} else {
|
||||
titleID = R.string.waiting_title;
|
||||
message = LocUtils
|
||||
.getQuantityString( activity, R.plurals.invite_msg_fmt,
|
||||
state.nMissing, state.nMissing );
|
||||
}
|
||||
|
||||
if ( ! invitesSent && showInviteButton ) {
|
||||
String ps = null;
|
||||
if ( state.nMissing > 1 ) {
|
||||
ps = LocUtils.getString( activity, R.string.invite_multiple );
|
||||
} else {
|
||||
boolean[] avail = NFCUtils.nfcAvail( activity );
|
||||
if ( avail[1] ) {
|
||||
ps = LocUtils.getString( activity, R.string.invite_if_nfc );
|
||||
}
|
||||
}
|
||||
if ( null != ps ) {
|
||||
message += "\n\n" + ps;
|
||||
}
|
||||
}
|
||||
|
||||
message += "\n\n" + LocUtils.getString( activity, R.string.invite_stays );
|
||||
}
|
||||
|
||||
AlertDialog.Builder ab = makeAlertBuilder()
|
||||
.setTitle( titleID )
|
||||
.setMessage( message );
|
||||
|
||||
OnClickListener lstnr = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dialog, int item ){
|
||||
if ( !state.relayMissing ||
|
||||
! state.connTypes.contains(CommsConnType.COMMS_CONN_RELAY) ) {
|
||||
Assert.assertTrue( 0 < state.nMissing );
|
||||
if ( state.summary.hasRematchInfo() ) {
|
||||
tryRematchInvites( true );
|
||||
} else if ( state.summary.hasInviteInfo() ) {
|
||||
tryOtherInvites();
|
||||
} else {
|
||||
callInviteChoices( sentInfo[0] );
|
||||
}
|
||||
} else {
|
||||
askDropRelay();
|
||||
}
|
||||
}
|
||||
};
|
||||
alert.setNoDismissListenerPos( ab, buttonTxt, lstnr );
|
||||
|
||||
if ( showNeutButton ) {
|
||||
lstnr = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dialog,
|
||||
int item ) {
|
||||
String msg = sentInfo[0].getAsText( activity );
|
||||
makeOkOnlyBuilder( msg )
|
||||
.setAction( Action.INVITE_INFO )
|
||||
.show();
|
||||
}
|
||||
};
|
||||
alert.setNoDismissListenerNeut( ab, R.string.newgame_invite_more,
|
||||
lstnr );
|
||||
}
|
||||
if ( showInviteButton ) {
|
||||
lstnr = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface di, int item ) {
|
||||
alert.dismiss();
|
||||
finish();
|
||||
}
|
||||
};
|
||||
alert.setNoDismissListenerNeg( ab, R.string.button_close, lstnr );
|
||||
}
|
||||
|
||||
dialog = ab.create();
|
||||
|
||||
// Hack: I can't prevent screen rotation from duplicating this alert
|
||||
dismissInviteAlert();
|
||||
m_inviteAlert = alert;
|
||||
alert.setOnCancelListener( new DBAlert.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancelled( XWDialogFragment frag ) {
|
||||
finish();
|
||||
}
|
||||
} );
|
||||
}
|
||||
return dialog;
|
||||
} // makeInviteDialog
|
||||
|
||||
public BoardDelegate( Delegator delegator, Bundle savedInstanceState )
|
||||
{
|
||||
super( delegator, savedInstanceState, R.layout.board, R.menu.board_menu );
|
||||
|
@ -829,19 +671,18 @@ public class BoardDelegate extends DelegateBase
|
|||
// loop of showing the rationale over and over. Android will always tell
|
||||
// us to show the rationale, but if we've done it already we need to go
|
||||
// straight to asking for the permission.
|
||||
private void callInviteChoices( final SentInvitesInfo info )
|
||||
private void callInviteChoices()
|
||||
{
|
||||
Perms23.tryGetPermsNA( this, Perm.READ_PHONE_STATE,
|
||||
R.string.phone_state_rationale,
|
||||
R.string.key_na_perms_phonestate,
|
||||
Action.ASKED_PHONE_STATE, info );
|
||||
Action.ASKED_PHONE_STATE );
|
||||
}
|
||||
|
||||
private void showInviteChoicesThen( Object[] params )
|
||||
private void showInviteChoicesThen()
|
||||
{
|
||||
SentInvitesInfo info = (SentInvitesInfo)params[0];
|
||||
NetLaunchInfo nli = nliForMe();
|
||||
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, info, nli );
|
||||
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, nli );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1221,7 +1062,7 @@ public class BoardDelegate extends DelegateBase
|
|||
break;
|
||||
|
||||
case ASKED_PHONE_STATE:
|
||||
showInviteChoicesThen( params );
|
||||
showInviteChoicesThen();
|
||||
break;
|
||||
|
||||
case BLANK_PICKED:
|
||||
|
@ -1309,7 +1150,7 @@ public class BoardDelegate extends DelegateBase
|
|||
finish();
|
||||
break;
|
||||
case ASKED_PHONE_STATE:
|
||||
showInviteChoicesThen( params );
|
||||
showInviteChoicesThen();
|
||||
break;
|
||||
case INVITE_SMS_DATA:
|
||||
Perms23.Perm[] perms = (Perms23.Perm[])params[2];
|
||||
|
@ -1411,8 +1252,9 @@ public class BoardDelegate extends DelegateBase
|
|||
case SMS_USER:
|
||||
case EMAIL:
|
||||
case CLIPBOARD:
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi, 1,
|
||||
1 + m_nGuestDevs );
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
|
||||
1, // nPlayers
|
||||
1 + m_mySIS.nGuestDevs ); // fc
|
||||
if ( m_relayMissing ) {
|
||||
nli.removeAddress( CommsConnType.COMMS_CONN_RELAY );
|
||||
}
|
||||
|
@ -1526,17 +1368,6 @@ public class BoardDelegate extends DelegateBase
|
|||
//////////////////////////////////////////////////
|
||||
// TransportProcs.TPMsgHandler interface
|
||||
//////////////////////////////////////////////////
|
||||
@Override
|
||||
public void tpmRelayConnd( final String room, final int devOrder,
|
||||
final boolean allHere, final int nMissing )
|
||||
{
|
||||
runOnUiThread( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
handleConndMessage( room, devOrder, allHere, nMissing ); // from here too
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tpmRelayErrorProc( TransportProcs.XWRELAY_ERROR relayErr )
|
||||
|
@ -1655,14 +1486,38 @@ public class BoardDelegate extends DelegateBase
|
|||
// Do we need this?
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// InvitesNeededAlert.Callbacks
|
||||
////////////////////////////////////////////////////////////
|
||||
@Override
|
||||
public DelegateBase getDelegate() { return this; }
|
||||
|
||||
@Override
|
||||
public void onCloseClicked()
|
||||
{
|
||||
post( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InvitesNeededAlert.dismiss();
|
||||
finish();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInviteClicked()
|
||||
{
|
||||
callInviteChoices();
|
||||
}
|
||||
|
||||
private byte[] getInvite()
|
||||
{
|
||||
byte[] result = null;
|
||||
if ( 0 < m_mySIS.nMissing // Isn't there a better test??
|
||||
&& DeviceRole.SERVER_ISSERVER == m_gi.serverRole ) {
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_gi );
|
||||
Assert.assertTrue( 0 <= m_nGuestDevs );
|
||||
nli.forceChannel = 1 + m_nGuestDevs;
|
||||
Assert.assertTrue( 0 <= m_mySIS.nGuestDevs );
|
||||
nli.forceChannel = 1 + m_mySIS.nGuestDevs;
|
||||
|
||||
for ( Iterator<CommsConnType> iter = m_connTypes.iterator();
|
||||
iter.hasNext(); ) {
|
||||
|
@ -1774,68 +1629,6 @@ public class BoardDelegate extends DelegateBase
|
|||
return xpKey;
|
||||
}
|
||||
|
||||
private void handleConndMessage( String room, int devOrder, // <- hostID
|
||||
boolean allHere, int nMissing )
|
||||
{
|
||||
boolean skipDismiss = false;
|
||||
|
||||
int naMsg = 0;
|
||||
int naKey = 0;
|
||||
String toastStr = null;
|
||||
m_mySIS.nMissing = nMissing;
|
||||
if ( allHere ) {
|
||||
// All players have now joined the game. The device that
|
||||
// created the room will assign tiles. Then it will be
|
||||
// the first player's turn
|
||||
|
||||
// Skip this until there's a way to show it only once per game
|
||||
if ( false ) {
|
||||
toastStr = getString( R.string.msg_relay_all_here_fmt, room );
|
||||
if ( devOrder > 1 ) {
|
||||
naMsg = R.string.not_again_conndall;
|
||||
naKey = R.string.key_notagain_conndall;
|
||||
}
|
||||
}
|
||||
} else if ( nMissing > 0 ) {
|
||||
if ( m_summary.hasRematchInfo() ) {
|
||||
skipDismiss = !tryRematchInvites( false );
|
||||
} else if ( m_summary.hasInviteInfo() ) {
|
||||
skipDismiss = !tryOtherInvites();
|
||||
} else if ( showInviteAlertIf() ) {
|
||||
skipDismiss = true;
|
||||
invalidateOptionsMenuIf();
|
||||
} else {
|
||||
toastStr = getQuantityString( R.plurals.msg_relay_waiting_fmt, nMissing,
|
||||
devOrder, room, nMissing );
|
||||
if ( devOrder == 1 ) {
|
||||
naMsg = R.string.not_again_conndfirst;
|
||||
naKey = R.string.key_notagain_conndfirst;
|
||||
} else {
|
||||
naMsg = R.string.not_again_conndmid;
|
||||
naKey = R.string.key_notagain_conndmid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( null != toastStr ) {
|
||||
Log.i( TAG, "handleConndMessage(): toastStr: %s", toastStr );
|
||||
m_mySIS.toastStr = toastStr;
|
||||
if ( naMsg == 0 ) {
|
||||
onPosButton( Action.SHOW_EXPL_ACTION, null );
|
||||
} else {
|
||||
makeNotAgainBuilder( naMsg, naKey, Action.SHOW_EXPL_ACTION )
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !skipDismiss ) {
|
||||
dismissInviteAlert( nMissing, true ); // NO!!!
|
||||
}
|
||||
|
||||
invalidateOptionsMenuIf();
|
||||
setTitle();
|
||||
} // handleConndMessage
|
||||
|
||||
private class BoardUtilCtxt extends UtilCtxtImpl {
|
||||
|
||||
public BoardUtilCtxt()
|
||||
|
@ -2162,34 +1955,20 @@ public class BoardDelegate extends DelegateBase
|
|||
// missing or not.
|
||||
@Override
|
||||
public void informMissing( boolean isServer, CommsConnTypeSet connTypes,
|
||||
int nDevs, final int nMissing )
|
||||
int nDevs, int nMissing )
|
||||
{
|
||||
boolean doDismiss = true;
|
||||
m_connTypes = connTypes;
|
||||
Assert.assertTrue( isServer || 0 == nMissing );
|
||||
// DbgUtils.logf( "BoardDelegate.informMissing(isServer=%b, nDevs=%d, nMissing=%d)",
|
||||
// isServer, nDevs, nMissing );
|
||||
m_nGuestDevs = nDevs;
|
||||
|
||||
m_mySIS.nMissing = nMissing; // will be 0 unless isServer is true
|
||||
setTitle();
|
||||
m_mySIS.nGuestDevs = nDevs;
|
||||
m_connTypes = connTypes;
|
||||
|
||||
if ( null != connTypes && 0 == connTypes.size() ) {
|
||||
askNoAddrsDelete();
|
||||
} else if ( 0 < nMissing && isServer ) {
|
||||
doDismiss = false;
|
||||
post( new Runnable() {
|
||||
if ( isServer ) {
|
||||
runOnUiThread( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showInviteAlertIf();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// If we might have put up an alert earlier, take it down
|
||||
if ( doDismiss ) {
|
||||
dismissInviteAlert( nMissing, !m_relayMissing );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2570,42 +2349,6 @@ public class BoardDelegate extends DelegateBase
|
|||
}
|
||||
}
|
||||
|
||||
private void dismissInviteAlert( final int nMissing, final boolean connected )
|
||||
{
|
||||
runOnUiThread( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InviteChoicesAlert.dismissAny();
|
||||
|
||||
if ( m_relayMissing && connected ) {
|
||||
m_relayMissing = false;
|
||||
}
|
||||
// Why this m_relayMissing thing?
|
||||
if ( 0 == nMissing /* || !m_relayMissing*/ ) {
|
||||
// Log.d( TAG, "dismissing invite alert %H", m_inviteAlert );
|
||||
dismissInviteAlert();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private void dismissInviteAlert()
|
||||
{
|
||||
if ( null != m_inviteAlert ) {
|
||||
// Play Console reports a crash inside DialogFragment.dismiss()
|
||||
// resulting from getFragmentManager() returning null. That
|
||||
// probably means I'm on the way out and can safely drop? Let's
|
||||
// see....
|
||||
try {
|
||||
m_inviteAlert.dismiss();
|
||||
} catch ( NullPointerException | IllegalStateException ex ) {
|
||||
Log.ex( TAG, ex );
|
||||
}
|
||||
m_inviteAlert = null;
|
||||
m_haveStartedShowing = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void pingBTRemotes()
|
||||
{
|
||||
if ( null != m_connTypes
|
||||
|
@ -2687,29 +2430,14 @@ public class BoardDelegate extends DelegateBase
|
|||
// This is failing sometimes, and so the null == m_inviteAlert test means
|
||||
// we never post it. BUT on a lot of devices without the test we wind up
|
||||
// trying over and over to put the thing up.
|
||||
private boolean showInviteAlertIf()
|
||||
private void showInviteAlertIf()
|
||||
{
|
||||
boolean success = false;
|
||||
DbgUtils.assertOnUIThread();
|
||||
if ( alertOrderAt( StartAlertOrder.INVITE ) ) {
|
||||
if ( ! m_haveStartedShowing && null == m_inviteAlert
|
||||
&& m_mySIS.nMissing > 0 && !isFinishing() ) {
|
||||
InviteAlertState ias = new InviteAlertState();
|
||||
ias.summary = m_summary;
|
||||
ias.gi = m_gi;
|
||||
ias.relayMissing = m_relayMissing;
|
||||
ias.connTypes = m_connTypes;
|
||||
ias.rowid = m_rowid;
|
||||
ias.nMissing = m_mySIS.nMissing;
|
||||
showDialogFragment( DlgID.DLG_INVITE, ias );
|
||||
m_haveStartedShowing = true;
|
||||
success = true;
|
||||
} else {
|
||||
alertOrderIncrIfAt( StartAlertOrder.INVITE );
|
||||
if ( alertOrderAt( StartAlertOrder.INVITE ) && ! isFinishing() ) {
|
||||
boolean isRematch = null != m_summary && m_summary.hasRematchInfo();
|
||||
InvitesNeededAlert.showOrHide( this, m_mySIS.nGuestDevs,
|
||||
m_mySIS.nMissing, isRematch );
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private boolean doZoom( int zoomBy )
|
||||
{
|
||||
|
@ -2814,8 +2542,8 @@ public class BoardDelegate extends DelegateBase
|
|||
for ( int ii = 0; ii < m_missingDevs.length; ++ii ) {
|
||||
String dev = m_missingDevs[ii];
|
||||
int nPlayers = m_missingCounts[ii];
|
||||
Assert.assertTrue( 0 <= m_nGuestDevs );
|
||||
int forceChannel = ii + m_nGuestDevs + 1;
|
||||
Assert.assertTrue( 0 <= m_mySIS.nGuestDevs );
|
||||
int forceChannel = ii + m_mySIS.nGuestDevs + 1;
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
|
||||
nPlayers, forceChannel )
|
||||
.setRemotesAreRobots( m_remotesAreRobots );
|
||||
|
@ -3177,7 +2905,7 @@ public class BoardDelegate extends DelegateBase
|
|||
private NetLaunchInfo nliForMe()
|
||||
{
|
||||
int numHere = 1;
|
||||
int forceChannel = 1;
|
||||
int forceChannel = 1 + m_mySIS.nGuestDevs;
|
||||
NetLaunchInfo nli = new NetLaunchInfo( m_activity, m_summary, m_gi,
|
||||
numHere, forceChannel );
|
||||
return nli;
|
||||
|
@ -3314,7 +3042,6 @@ public class BoardDelegate extends DelegateBase
|
|||
DBUtils.recordInviteSent( m_activity, m_rowid, means, dev );
|
||||
|
||||
if ( !invitesSent ) {
|
||||
dismissInviteAlert();
|
||||
Log.d( TAG, "recordInviteSent(): redoing invite alert" );
|
||||
showInviteAlertIf();
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ public class CommsTransport implements TransportProcs,
|
|||
public void relayConnd( String room, int devOrder, boolean allHere,
|
||||
int nMissing )
|
||||
{
|
||||
m_tpHandler.tpmRelayConnd( room, devOrder, allHere, nMissing );
|
||||
// m_tpHandler.tpmRelayConnd( room, devOrder, allHere, nMissing );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -99,7 +99,7 @@ public class DBAlert extends XWDialogFragment {
|
|||
|
||||
if ( null == dialog ) {
|
||||
Log.e( TAG, "no dialog for %s from %s", getDlgID(), activity );
|
||||
Assert.failDbg();
|
||||
// Assert.failDbg(); // remove: better to see what users will see
|
||||
dialog = LocUtils.makeAlertBuilder( activity )
|
||||
.setMessage( "Unable to create " + getDlgID() + " Alert" )
|
||||
.setPositiveButton( "Bummer", null )
|
||||
|
|
|
@ -519,7 +519,7 @@ public abstract class DelegateBase implements DlgClickNotify,
|
|||
protected void show( XWDialogFragment df )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
if ( m_activity instanceof XWActivity ) {
|
||||
if ( null != df && m_activity instanceof XWActivity ) {
|
||||
((XWActivity)m_activity).show( df );
|
||||
} else {
|
||||
Assert.failDbg();
|
||||
|
@ -596,10 +596,9 @@ public abstract class DelegateBase implements DlgClickNotify,
|
|||
}
|
||||
|
||||
protected void showInviteChoicesThen( Action action,
|
||||
DBUtils.SentInvitesInfo info,
|
||||
NetLaunchInfo nli )
|
||||
{
|
||||
m_dlgDelegate.showInviteChoicesThen( action, info, nli );
|
||||
m_dlgDelegate.showInviteChoicesThen( action, nli );
|
||||
}
|
||||
|
||||
public Builder makeOkOnlyBuilder( int msgID )
|
||||
|
|
|
@ -401,12 +401,11 @@ public class DlgDelegate {
|
|||
}
|
||||
|
||||
public void showInviteChoicesThen( final Action action,
|
||||
SentInvitesInfo info,
|
||||
NetLaunchInfo nli )
|
||||
{
|
||||
DlgState state = new DlgState( DlgID.INVITE_CHOICES_THEN )
|
||||
.setAction( action )
|
||||
.setParams( info, nli );
|
||||
.setParams( nli );
|
||||
m_dlgt.show( state );
|
||||
}
|
||||
|
||||
|
|
|
@ -85,11 +85,8 @@ public class InviteChoicesAlert extends DlgDelegateAlert
|
|||
NetLaunchInfo nli = null;
|
||||
Object[] params = state.getParams();
|
||||
if ( null != params ) {
|
||||
if ( 0 < params.length && params[0] instanceof SentInvitesInfo ) {
|
||||
lastMeans = ((SentInvitesInfo)params[0]).getLastMeans();
|
||||
}
|
||||
if ( 1 < params.length && params[1] instanceof NetLaunchInfo ) {
|
||||
nli = (NetLaunchInfo)params[1];
|
||||
if ( 0 < params.length && params[0] instanceof NetLaunchInfo ) {
|
||||
nli = (NetLaunchInfo)params[0];
|
||||
}
|
||||
}
|
||||
means.add( InviteMeans.EMAIL );
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.widget.ImageView;
|
|||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -238,6 +239,11 @@ public class InviteView extends ScrollView
|
|||
public void run() {
|
||||
ImageView iv = (ImageView)findViewById( R.id.qr_view );
|
||||
iv.setImageBitmap( bitmap );
|
||||
if ( BuildConfig.NON_RELEASE ) {
|
||||
TextView tv = (TextView)findViewById( R.id.qr_url );
|
||||
tv.setVisibility( View.VISIBLE );
|
||||
tv.setText( url );
|
||||
}
|
||||
post ( new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
|
@ -0,0 +1,199 @@
|
|||
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
|
||||
/*
|
||||
* Copyright 2009 - 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
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
package org.eehouse.android.xw4;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.DialogInterface;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
import org.eehouse.android.xw4.Perms23.Perm;
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
|
||||
class InvitesNeededAlert {
|
||||
private static final String TAG = InvitesNeededAlert.class.getSimpleName();
|
||||
|
||||
private static InvitesNeededAlert[] sInstance = {null};
|
||||
|
||||
private DBAlert mAlert;
|
||||
private State mState;
|
||||
private Callbacks mCallbacks;
|
||||
private DelegateBase mDelegate;
|
||||
|
||||
private static class State implements Serializable {
|
||||
int nDevsSeen;
|
||||
int nPlayersMissing;
|
||||
boolean isRematch;
|
||||
|
||||
State( int nDevs, int nPlayers, boolean rematch )
|
||||
{
|
||||
nDevsSeen = nDevs;
|
||||
nPlayersMissing = nPlayers;
|
||||
isRematch = rematch;
|
||||
}
|
||||
}
|
||||
|
||||
interface Callbacks {
|
||||
DelegateBase getDelegate();
|
||||
void onCloseClicked();
|
||||
void onInviteClicked();
|
||||
}
|
||||
|
||||
static void showOrHide( Callbacks callbacks, int nDevsSeen, int nPlayersMissing,
|
||||
boolean isRematch )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
InvitesNeededAlert self = sInstance[0];
|
||||
Log.d( TAG, "showOnceIf(nDevsSeen=%d, nPlayersMissing=%d); self: %s",
|
||||
nDevsSeen, nPlayersMissing, self );
|
||||
|
||||
if ( null == self && 0 == nPlayersMissing ) {
|
||||
// cool: need and have nothing, so do nothing
|
||||
} else if ( 0 < nPlayersMissing && null == self ) { // Need but don't have
|
||||
makeNew( callbacks, nDevsSeen, nPlayersMissing, isRematch );
|
||||
} else if ( 0 == nPlayersMissing && null != self ) { // Have and need to close
|
||||
close( self );
|
||||
} else if ( null != self && nPlayersMissing != self.mState.nPlayersMissing ) {
|
||||
close( self );
|
||||
makeNew( callbacks, nDevsSeen, nPlayersMissing, isRematch );
|
||||
} else if ( null != self && nPlayersMissing == self.mState.nPlayersMissing ) {
|
||||
// nothing to do
|
||||
} else {
|
||||
Assert.failDbg();
|
||||
}
|
||||
}
|
||||
|
||||
static Dialog make( Callbacks callbacks, DBAlert alert, Object[] params )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
InvitesNeededAlert self = sInstance[0];
|
||||
return self.makeImpl( callbacks, alert, params );
|
||||
}
|
||||
|
||||
static void dismiss()
|
||||
{
|
||||
Log.d( TAG, "dismiss()" );
|
||||
DbgUtils.assertOnUIThread();
|
||||
InvitesNeededAlert self = sInstance[0];
|
||||
if ( null != self ) {
|
||||
close( self );
|
||||
}
|
||||
}
|
||||
|
||||
private static void makeNew( Callbacks callbacks,
|
||||
int nDevsSeen, int nPlayersMissing, boolean isRematch )
|
||||
{
|
||||
Log.d( TAG, "makeNew(nDevsSeen=%d, nPlayersMissing=%d)", nDevsSeen, nPlayersMissing );
|
||||
State state = new State( nDevsSeen, nPlayersMissing, isRematch );
|
||||
InvitesNeededAlert self = new InvitesNeededAlert( callbacks, state );
|
||||
callbacks.getDelegate().showDialogFragment( DlgID.DLG_INVITE, state );
|
||||
}
|
||||
|
||||
private static void close( InvitesNeededAlert self )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
Assert.assertTrueNR( self == sInstance[0] );
|
||||
sInstance[0] = null;
|
||||
if ( null != self.mAlert ) {
|
||||
InviteChoicesAlert.dismissAny();
|
||||
self.mAlert.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private InvitesNeededAlert( Callbacks callbacks, State state )
|
||||
{
|
||||
mState = state;
|
||||
mCallbacks = callbacks;
|
||||
mDelegate = callbacks.getDelegate();
|
||||
DbgUtils.assertOnUIThread();
|
||||
Assert.assertTrueNR( null == sInstance[0] );
|
||||
sInstance[0] = this;
|
||||
}
|
||||
|
||||
private Dialog makeImpl( Callbacks callbacks, final DBAlert alert,
|
||||
Object[] params )
|
||||
{
|
||||
Dialog result = null;
|
||||
State state = (State)params[0];
|
||||
mAlert = alert;
|
||||
|
||||
Context context = mDelegate.getActivity();
|
||||
String title;
|
||||
|
||||
boolean isRematch = state.isRematch;
|
||||
if ( isRematch ) {
|
||||
title = LocUtils.getString( context, R.string.waiting_rematch_title );
|
||||
} else {
|
||||
title = LocUtils
|
||||
.getQuantityString( context, R.plurals.waiting_title_fmt,
|
||||
state.nPlayersMissing, state.nPlayersMissing );
|
||||
}
|
||||
|
||||
String message = LocUtils
|
||||
.getQuantityString( context, R.plurals.invite_msg_fmt,
|
||||
state.nPlayersMissing, state.nPlayersMissing );
|
||||
message += "\n\n"
|
||||
+ LocUtils.getString( context, R.string.invite_msg_extra );
|
||||
|
||||
if ( isRematch ) {
|
||||
message += "\n\n"
|
||||
+ LocUtils.getString( context, R.string.invite_msg_extra_rematch );
|
||||
}
|
||||
|
||||
AlertDialog.Builder ab = mDelegate.makeAlertBuilder()
|
||||
.setTitle( title )
|
||||
.setMessage( message );
|
||||
|
||||
alert.setNoDismissListenerPos( ab, R.string.newgame_invite,
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
onPosClick();
|
||||
}
|
||||
} );
|
||||
|
||||
alert.setNoDismissListenerNeg( ab, R.string.button_close,
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
onNegClick();
|
||||
}
|
||||
} );
|
||||
|
||||
result = ab.create();
|
||||
return result;
|
||||
}
|
||||
|
||||
private void onPosClick()
|
||||
{
|
||||
mCallbacks.onInviteClicked();
|
||||
}
|
||||
|
||||
private void onNegClick()
|
||||
{
|
||||
Log.d( TAG, "onNegClick()" );
|
||||
mCallbacks.onCloseClicked();
|
||||
}
|
||||
}
|
|
@ -65,8 +65,8 @@ public interface TransportProcs {
|
|||
boolean relayNoConnProc( byte[] buf, String msgNo, String relayID );
|
||||
|
||||
public interface TPMsgHandler {
|
||||
public void tpmRelayConnd( String room, int devOrder, boolean allHere,
|
||||
int nMissing );
|
||||
// public void tpmRelayConnd( String room, int devOrder, boolean allHere,
|
||||
// int nMissing );
|
||||
public void tpmRelayErrorProc( XWRELAY_ERROR relayErr );
|
||||
public void tpmCountChanged( int newCount );
|
||||
}
|
||||
|
|
|
@ -91,6 +91,11 @@
|
|||
android:layout_gravity="center_horizontal"
|
||||
android:paddingTop="10dp"
|
||||
/>
|
||||
<TextView android:id="@+id/qr_url"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</RadioGroup>
|
||||
<TextView android:id="@+id/who_empty"
|
||||
|
|
|
@ -466,26 +466,34 @@
|
|||
The number of players missing is substituted for "%1$d". -->
|
||||
<plurals name="invite_msg_fmt">
|
||||
<item quantity="one">This game is waiting for one remote
|
||||
player. Would you like to invite someone to join—assuming you
|
||||
haven’t already?</item>
|
||||
player to respond to an invitation.</item>
|
||||
<item quantity="other">This game is waiting for %1$d remote
|
||||
players. Would you like to invite someone to join—assuming
|
||||
you haven’t already?</item>
|
||||
players to repond to invitations.</item>
|
||||
</plurals>
|
||||
<plurals name="invite_sent_fmt">
|
||||
<item quantity="one">You have already invited a remote player to
|
||||
this game. We are waiting for him/her to respond. Please
|
||||
use the re-invite button if you think the invitation did not go
|
||||
out.</item>
|
||||
<item quantity="other">You have already sent %1$d unique
|
||||
invitations for this game. We are waiting for %2$d of the
|
||||
recipients to respond. Please use the re-invite button if you
|
||||
think the invitations did not go out.</item>
|
||||
</plurals>
|
||||
<string name="invited_msg">This game was created from an
|
||||
invitation you received. As soon as it is able to connect to the
|
||||
sender and any other invitees have arrived play will
|
||||
begin.</string>
|
||||
|
||||
<string name="invite_msg_extra">You will see this message until
|
||||
all expected players have connected. If you’ve already sent an
|
||||
invitation and suspect it was lost, there’s no harm in sending
|
||||
another.</string>
|
||||
|
||||
<string name="invite_msg_extra_rematch">With rematches, all
|
||||
necessary invitations will have been sent automatically. But you
|
||||
can always send new ones if an invitee is not responding.</string>
|
||||
|
||||
<!-- <plurals name="invite_sent_fmt"> -->
|
||||
<!-- <item quantity="one">You have already invited a remote player to -->
|
||||
<!-- this game. We are waiting for him/her to respond. Please -->
|
||||
<!-- use the re-invite button if you think the invitation did not go -->
|
||||
<!-- out.</item> -->
|
||||
<!-- <item quantity="other">You have already sent %1$d unique -->
|
||||
<!-- invitations for this game. We are waiting for %2$d of the -->
|
||||
<!-- recipients to respond. Please use the re-invite button if you -->
|
||||
<!-- think the invitations did not go out.</item> -->
|
||||
<!-- </plurals> -->
|
||||
<!-- <string name="invited_msg">This game was created from an -->
|
||||
<!-- invitation you received. As soon as it is able to connect to the -->
|
||||
<!-- sender and any other invitees have arrived play will -->
|
||||
<!-- begin.</string> -->
|
||||
<!-- Appended to message above if local device has NFC available -->
|
||||
<string name="invite_if_nfc">Or just Tap to Invite -- if the other
|
||||
device also has Android Beaming and is nearby.</string>
|
||||
|
@ -2245,7 +2253,10 @@
|
|||
to make more games visible.\n\n(If you later want to unhide the
|
||||
buttons go to the Appearance section of App settings).
|
||||
</string>
|
||||
<string name="waiting_title">Waiting for players</string>
|
||||
<plurals name="waiting_title_fmt">
|
||||
<item quantity="one">Waiting for player</item>
|
||||
<item quantity="other">Waiting for %1$d players</item>
|
||||
</plurals>
|
||||
<!-- Button for alert with title above -->
|
||||
<string name="waiting_invite_title">Waiting for response</string>
|
||||
<string name="waiting_rematch_title">Rematch in progress</string>
|
||||
|
|
|
@ -194,7 +194,8 @@ static XWStreamCtxt* messageStreamWithHeader( ServerCtxt* server, XWEnv xwe,
|
|||
XP_U16 devIndex, XW_Proto code );
|
||||
static XP_Bool handleRegistrationMsg( ServerCtxt* server, XWEnv xwe,
|
||||
XWStreamCtxt* stream );
|
||||
static XP_S8 registerRemotePlayer( ServerCtxt* server, XWStreamCtxt* stream );
|
||||
static XP_S8 registerRemotePlayer( ServerCtxt* server, XWEnv xwe,
|
||||
XWStreamCtxt* stream );
|
||||
static void sendInitialMessage( ServerCtxt* server, XWEnv xwe );
|
||||
static void sendBadWordMsgs( ServerCtxt* server, XWEnv xwe );
|
||||
static XP_Bool handleIllegalWord( ServerCtxt* server, XWEnv xwe,
|
||||
|
@ -914,7 +915,7 @@ handleRegistrationMsg( ServerCtxt* server, XWEnv xwe, XWStreamCtxt* stream )
|
|||
XP_S8 prevIndex = -1;
|
||||
#endif
|
||||
for ( ; ii < playersInMsg; ++ii ) {
|
||||
clientIndex = registerRemotePlayer( server, stream );
|
||||
clientIndex = registerRemotePlayer( server, xwe, stream );
|
||||
if ( -1 == clientIndex ) {
|
||||
success = XP_FALSE;
|
||||
break;
|
||||
|
@ -1790,7 +1791,7 @@ findFirstPending( ServerCtxt* server, ServerPlayer** playerP )
|
|||
} /* findFirstPending */
|
||||
|
||||
static XP_S8
|
||||
registerRemotePlayer( ServerCtxt* server, XWStreamCtxt* stream )
|
||||
registerRemotePlayer( ServerCtxt* server, XWEnv xwe, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_S8 deviceIndex = -1;
|
||||
XP_PlayerAddr channelNo;
|
||||
|
@ -1839,6 +1840,8 @@ registerRemotePlayer( ServerCtxt* server, XWStreamCtxt* stream )
|
|||
}
|
||||
|
||||
player->deviceIndex = deviceIndex;
|
||||
|
||||
informMissing( server, xwe );
|
||||
}
|
||||
return deviceIndex;
|
||||
} /* registerRemotePlayer */
|
||||
|
|
Loading…
Add table
Reference in a new issue