first step in showing a different alert for an unconnected game where

an invitation's already been sent. It's stored in a new DB table, and
user can display info about how and to what device it was sent.
This commit is contained in:
Eric House 2016-01-08 19:05:22 -08:00
parent 7e714ae547
commit e60945733f
8 changed files with 663 additions and 497 deletions

File diff suppressed because it is too large Load diff

View file

@ -545,6 +545,12 @@
players. Would you like to invite someone to join -- assuming players. Would you like to invite someone to join -- assuming
you haven\'t already?</item> you haven\'t already?</item>
</plurals> </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 connect back.</item>
<item quantity="other">You have already invited %1$d players to
this game. We are waiting for them to connect back.</item>
</plurals>
<!-- Appended to message above if local device has NFC available --> <!-- Appended to message above if local device has NFC available -->
<string name="invite_if_nfc">Or just Tap to Invite -- if the other <string name="invite_if_nfc">Or just Tap to Invite -- if the other
@ -1173,6 +1179,7 @@
it immediately because an email or messaging app will be it immediately because an email or messaging app will be
launched to send your invitation. --> launched to send your invitation. -->
<string name="newgame_invite">Invite now</string> <string name="newgame_invite">Invite now</string>
<string name="newgame_invite_more">More info</string>
<string name="newgame_drop_relay">Drop Relay</string> <string name="newgame_drop_relay">Drop Relay</string>
<!-- section separator (white-on-gray bar) for third section: <!-- section separator (white-on-gray bar) for third section:
@ -2439,12 +2446,14 @@
<string name="waiting_title">Waiting for players</string> <string name="waiting_title">Waiting for players</string>
<!-- Button for alert with title above --> <!-- Button for alert with title above -->
<string name="waiting_invite_title">Waiting for response</string>
<!-- Button for alert with title above -->
<string name="button_wait">Wait</string> <string name="button_wait">Wait</string>
<string name="invite_stays">(This dialog will stay up until all <string name="invite_stays">(This dialog will stay up until all
remote players have connected. You can close the game if you remote players have connected. You can close the game if you
expect it to take a while. They will still be able to expect it to take a while. Remote players will still be able to
connect.)</string> connect, and you will be notified when they do.)</string>
<string name="nfc_just_tap">To invite via NFC just touch the back <string name="nfc_just_tap">To invite via NFC just touch the back
of this device against the one you want to invite—any time the of this device against the one you want to invite—any time the

View file

@ -464,6 +464,12 @@
sreyalp. Dluow uoy ekil ot etivni enoemos ot nioj -- gnimussa sreyalp. Dluow uoy ekil ot etivni enoemos ot nioj -- gnimussa
uoy nevah\'t ?ydaerla</item> uoy nevah\'t ?ydaerla</item>
</plurals> </plurals>
<plurals name="invite_sent_fmt">
<item quantity="one">Uoy evah ydaerla detivni a etomer reyalp ot
siht emag. Ew era gnitiaw rof reh/mih ot tcennoc kcab.</item>
<item quantity="other">Uoy evah ydaerla detivni %1$d sreyalp ot
siht emag. Ew era gnitiaw rof meht ot tcennoc kcab.</item>
</plurals>
<!-- Appended to message above if local device has NFC available --> <!-- Appended to message above if local device has NFC available -->
<string name="invite_if_nfc">Ro tsuj Pat ot Etivni -- fi eht rehto <string name="invite_if_nfc">Ro tsuj Pat ot Etivni -- fi eht rehto
ecived osla sah Diordna Gnimaeb dna si ybraen.</string> ecived osla sah Diordna Gnimaeb dna si ybraen.</string>
@ -1009,6 +1015,7 @@
it immediately because an email or messaging app will be it immediately because an email or messaging app will be
launched to send your invitation. --> launched to send your invitation. -->
<string name="newgame_invite">Etivni won</string> <string name="newgame_invite">Etivni won</string>
<string name="newgame_invite_more">Erom ofni</string>
<string name="newgame_drop_relay">Pord Yaler</string> <string name="newgame_drop_relay">Pord Yaler</string>
<!-- section separator (white-on-gray bar) for third section: <!-- section separator (white-on-gray bar) for third section:
bluetooth games --> bluetooth games -->
@ -2091,11 +2098,13 @@
</string> </string>
<string name="waiting_title">Gnitiaw rof sreyalp</string> <string name="waiting_title">Gnitiaw rof sreyalp</string>
<!-- Button for alert with title above --> <!-- Button for alert with title above -->
<string name="waiting_invite_title">Gnitiaw rof esnopser</string>
<!-- Button for alert with title above -->
<string name="button_wait">Tiaw</string> <string name="button_wait">Tiaw</string>
<string name="invite_stays">sIht( golaid lliw yats pu litnu lla <string name="invite_stays">sIht( golaid lliw yats pu litnu lla
etomer sreyalp evah detcennoc. Uoy nac esolc eht emag fi uoy etomer sreyalp evah detcennoc. Uoy nac esolc eht emag fi uoy
tcepxe ti ot ekat a elihw. Yeht lliw llits eb elba ot tcepxe ti ot ekat a elihw. Etomer sreyalp lliw llits eb elba ot
tcennoc.)</string> ,tcennoc dna uoy lliw eb deifiton nehw yeht od.)</string>
<string name="nfc_just_tap">Ot etivni aiv CFN tsuj hcuot eht kcab <string name="nfc_just_tap">Ot etivni aiv CFN tsuj hcuot eht kcab
fo siht ecived tsniaga eht eno uoy tnaw ot yna—etivni emit eht fo siht ecived tsniaga eht eno uoy tnaw ot yna—etivni emit eht
emag si nepo.</string> emag si nepo.</string>

View file

@ -464,6 +464,12 @@
PLAYERS. WOULD YOU LIKE TO INVITE SOMEONE TO JOIN -- ASSUMING PLAYERS. WOULD YOU LIKE TO INVITE SOMEONE TO JOIN -- ASSUMING
YOU HAVEN\'T ALREADY?</item> YOU HAVEN\'T ALREADY?</item>
</plurals> </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 CONNECT BACK.</item>
<item quantity="other">YOU HAVE ALREADY INVITED %1$d PLAYERS TO
THIS GAME. WE ARE WAITING FOR THEM TO CONNECT BACK.</item>
</plurals>
<!-- Appended to message above if local device has NFC available --> <!-- Appended to message above if local device has NFC available -->
<string name="invite_if_nfc">OR JUST TAP TO INVITE -- IF THE OTHER <string name="invite_if_nfc">OR JUST TAP TO INVITE -- IF THE OTHER
DEVICE ALSO HAS ANDROID BEAMING AND IS NEARBY.</string> DEVICE ALSO HAS ANDROID BEAMING AND IS NEARBY.</string>
@ -1009,6 +1015,7 @@
it immediately because an email or messaging app will be it immediately because an email or messaging app will be
launched to send your invitation. --> launched to send your invitation. -->
<string name="newgame_invite">INVITE NOW</string> <string name="newgame_invite">INVITE NOW</string>
<string name="newgame_invite_more">MORE INFO</string>
<string name="newgame_drop_relay">DROP RELAY</string> <string name="newgame_drop_relay">DROP RELAY</string>
<!-- section separator (white-on-gray bar) for third section: <!-- section separator (white-on-gray bar) for third section:
bluetooth games --> bluetooth games -->
@ -2091,11 +2098,13 @@
</string> </string>
<string name="waiting_title">WAITING FOR PLAYERS</string> <string name="waiting_title">WAITING FOR PLAYERS</string>
<!-- Button for alert with title above --> <!-- Button for alert with title above -->
<string name="waiting_invite_title">WAITING FOR RESPONSE</string>
<!-- Button for alert with title above -->
<string name="button_wait">WAIT</string> <string name="button_wait">WAIT</string>
<string name="invite_stays">(THIS DIALOG WILL STAY UP UNTIL ALL <string name="invite_stays">(THIS DIALOG WILL STAY UP UNTIL ALL
REMOTE PLAYERS HAVE CONNECTED. YOU CAN CLOSE THE GAME IF YOU REMOTE PLAYERS HAVE CONNECTED. YOU CAN CLOSE THE GAME IF YOU
EXPECT IT TO TAKE A WHILE. THEY WILL STILL BE ABLE TO EXPECT IT TO TAKE A WHILE. REMOTE PLAYERS WILL STILL BE ABLE TO
CONNECT.)</string> CONNECT, AND YOU WILL BE NOTIFIED WHEN THEY DO.)</string>
<string name="nfc_just_tap">TO INVITE VIA NFC JUST TOUCH THE BACK <string name="nfc_just_tap">TO INVITE VIA NFC JUST TOUCH THE BACK
OF THIS DEVICE AGAINST THE ONE YOU WANT TO INVITE—ANY TIME THE OF THIS DEVICE AGAINST THE ONE YOU WANT TO INVITE—ANY TIME THE
GAME IS OPEN.</string> GAME IS OPEN.</string>

View file

@ -96,6 +96,7 @@ public class BoardDelegate extends DelegateBase
private View m_tradeButtons; private View m_tradeButtons;
private Button m_exchCommmitButton; private Button m_exchCommmitButton;
private Button m_exchCancelButton; private Button m_exchCancelButton;
private DBUtils.SentInvitesInfo m_sentInfo;
private ArrayList<String> m_pendingChats; private ArrayList<String> m_pendingChats;
@ -431,7 +432,15 @@ public class BoardDelegate extends DelegateBase
lstnr = new OnClickListener() { lstnr = new OnClickListener() {
public void onClick( DialogInterface dialog, public void onClick( DialogInterface dialog,
int item ) { int item ) {
if ( m_relayConnected || if ( null != m_sentInfo
&& m_sentInfo.getPlayerCount() >= m_nMissing ) {
// PENDING: probably want a new dialog here
// that includes "resend" and "new invitation"
// buttons, the latter allowing to address it
// differently. Might also want option to
// delete game here too.
showOKOnlyDialog( m_sentInfo.getAsText() );
} else if ( m_relayConnected ||
! m_connTypes.contains(CommsConnType.COMMS_CONN_RELAY) ) { ! m_connTypes.contains(CommsConnType.COMMS_CONN_RELAY) ) {
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION ); showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION );
} else { } else {
@ -504,21 +513,33 @@ public class BoardDelegate extends DelegateBase
buttonTxt = R.string.newgame_drop_relay; buttonTxt = R.string.newgame_drop_relay;
} }
} else { } else {
titleID = R.string.waiting_title; m_sentInfo = DBUtils.getInvitesFor( m_activity, m_rowid );
message = getQuantityString( R.plurals.invite_msg_fmt, int nSent = m_sentInfo.getPlayerCount();
m_nMissing, m_nMissing ); boolean haveSent = nSent >= m_nMissing;
if ( haveSent ) {
String ps = null; titleID = R.string.waiting_invite_title;
if ( m_nMissing > 1 ) { message = getQuantityString( R.plurals.invite_sent_fmt,
ps = getString( R.string.invite_multiple ); nSent, nSent );
buttonTxt = R.string.newgame_invite_more;
} else { } else {
boolean[] avail = NFCUtils.nfcAvail( m_activity ); titleID = R.string.waiting_title;
if ( avail[1] ) { message = getQuantityString( R.plurals.invite_msg_fmt,
ps = getString( R.string.invite_if_nfc ); m_nMissing, m_nMissing );
}
} }
if ( null != ps ) {
message += "\n\n" + ps; if ( ! haveSent ) {
String ps = null;
if ( m_nMissing > 1 ) {
ps = getString( R.string.invite_multiple );
} else {
boolean[] avail = NFCUtils.nfcAvail( m_activity );
if ( avail[1] ) {
ps = getString( R.string.invite_if_nfc );
}
}
if ( null != ps ) {
message += "\n\n" + ps;
}
} }
message += "\n\n" + getString( R.string.invite_stays ); message += "\n\n" + getString( R.string.invite_stays );
@ -2416,6 +2437,9 @@ public class BoardDelegate extends DelegateBase
} }
break; break;
} }
DBUtils.recordInviteSent( m_activity, m_rowid,
m_missingMeans, dev );
} }
m_missingDevs = null; m_missingDevs = null;
m_missingCounts = null; m_missingCounts = null;

View file

@ -41,8 +41,9 @@ public class DBHelper extends SQLiteOpenHelper {
public static final String TABLE_NAME_STUDYLIST = "study"; public static final String TABLE_NAME_STUDYLIST = "study";
public static final String TABLE_NAME_LOC = "loc"; public static final String TABLE_NAME_LOC = "loc";
public static final String TABLE_NAME_PAIRS = "pairs"; public static final String TABLE_NAME_PAIRS = "pairs";
public static final String TABLE_NAME_INVITES = "invites";
private static final String DB_NAME = "xwdb"; private static final String DB_NAME = "xwdb";
private static final int DB_VERSION = 24; private static final int DB_VERSION = 25;
public static final String GAME_NAME = "GAME_NAME"; public static final String GAME_NAME = "GAME_NAME";
public static final String VISID = "VISID"; public static final String VISID = "VISID";
@ -104,6 +105,10 @@ public class DBHelper extends SQLiteOpenHelper {
public static final String BLESSED = "BLESSED"; public static final String BLESSED = "BLESSED";
public static final String XLATION = "XLATION"; public static final String XLATION = "XLATION";
public static final String ROW = "ROW";
public static final String MEANS = "MEANS";
public static final String TARGET = "TARGET";
public static final String TIMESTAMP = "TIMESTAMP";
private Context m_context; private Context m_context;
@ -194,6 +199,13 @@ public class DBHelper extends SQLiteOpenHelper {
,{ "UNIQUE", "(" + KEY + ")" } ,{ "UNIQUE", "(" + KEY + ")" }
}; };
private static final String[][] s_invitesSchema = {
{ ROW, "INTEGER" }
,{ TARGET, "TEXT" }
,{ MEANS, "INTEGER" }
,{ TIMESTAMP, "DATETIME DEFAULT CURRENT_TIMESTAMP" }
};
public DBHelper( Context context ) public DBHelper( Context context )
{ {
super( context, DB_NAME, null, DB_VERSION ); super( context, DB_NAME, null, DB_VERSION );
@ -217,6 +229,7 @@ public class DBHelper extends SQLiteOpenHelper {
createStudyTable( db ); createStudyTable( db );
createLocTable( db ); createLocTable( db );
createPairsTable( db ); createPairsTable( db );
createInvitesTable( db );
} }
@Override @Override
@ -283,6 +296,9 @@ public class DBHelper extends SQLiteOpenHelper {
if ( !madeSumTable ) { if ( !madeSumTable ) {
addSumColumn( db, EXTRAS ); addSumColumn( db, EXTRAS );
} }
case 24:
createInvitesTable( db );
break; break;
default: default:
db.execSQL( "DROP TABLE " + TABLE_NAME_SUM + ";" ); db.execSQL( "DROP TABLE " + TABLE_NAME_SUM + ";" );
@ -381,6 +397,11 @@ public class DBHelper extends SQLiteOpenHelper {
createTable( db, TABLE_NAME_PAIRS, s_pairsSchema ); createTable( db, TABLE_NAME_PAIRS, s_pairsSchema );
} }
private void createInvitesTable( SQLiteDatabase db )
{
createTable( db, TABLE_NAME_INVITES, s_invitesSchema );
}
// Move all existing games to the row previously named "cur games' // Move all existing games to the row previously named "cur games'
private void moveToCurGames( SQLiteDatabase db ) private void moveToCurGames( SQLiteDatabase db )
{ {

View file

@ -34,6 +34,8 @@ import android.net.Uri;
import android.os.Environment; import android.os.Environment;
import android.text.TextUtils; import android.text.TextUtils;
import java.sql.Timestamp;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -52,10 +54,11 @@ import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import junit.framework.Assert; import junit.framework.Assert;
import org.eehouse.android.xw4.DictUtils.DictLoc;
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
import org.eehouse.android.xw4.jni.*; import org.eehouse.android.xw4.jni.*;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.DictUtils.DictLoc;
import org.eehouse.android.xw4.loc.LocUtils; import org.eehouse.android.xw4.loc.LocUtils;
public class DBUtils { public class DBUtils {
@ -426,6 +429,84 @@ public class DBUtils {
return result; return result;
} }
public static class SentInvitesInfo {
public long m_rowid;
private int m_count = 0;
private InviteMeans m_means;
private String m_target;
private Timestamp m_timestamp;
private SentInvitesInfo( long rowID ) {
m_rowid = rowID;
}
private void addEntry( InviteMeans means, String target, Timestamp ts )
{
Assert.assertTrue( 0 == m_count );
++m_count;
m_means = means;
m_target = target;
m_timestamp = ts;
}
public int getPlayerCount() {
return m_count;
}
public String getAsText() {
return String.format( "Invite sent to dev %s via %s on %s", m_target,
m_means.toString(), m_timestamp.toString() );
}
}
public static SentInvitesInfo getInvitesFor( Context context, long rowid )
{
SentInvitesInfo result = new SentInvitesInfo( rowid );
String[] columns = { DBHelper.MEANS, DBHelper.TIMESTAMP, DBHelper.TARGET };
String selection = String.format( "%s = %d", DBHelper.ROW, rowid );
synchronized( s_dbHelper ) {
SQLiteDatabase db = s_dbHelper.getReadableDatabase();
Cursor cursor = db.query( DBHelper.TABLE_NAME_INVITES, columns,
selection, null, null, null, null );
if ( 0 < cursor.getCount() ) {
int indxMns = cursor.getColumnIndex( DBHelper.MEANS );
int indxTS = cursor.getColumnIndex( DBHelper.TIMESTAMP );
int indxTrgt = cursor.getColumnIndex( DBHelper.TARGET );
while ( cursor.moveToNext() ) {
InviteMeans means = InviteMeans.values()[cursor.getInt( indxMns )];
Timestamp ts = Timestamp.valueOf(cursor.getString(indxTS));
String target = cursor.getString( indxTrgt );
result.addEntry( means, target, ts );
}
}
cursor.close();
db.close();
}
return result;
}
// Only record the most recent for a given recipient! Or not. If I send to K via SMS
public static void recordInviteSent( Context context, long rowid,
InviteMeans means, String target )
{
ContentValues values = new ContentValues();
values.put( DBHelper.ROW, rowid );
values.put( DBHelper.MEANS, means.ordinal() );
values.put( DBHelper.TARGET, target );
initDB( context );
synchronized( s_dbHelper ) {
SQLiteDatabase db = s_dbHelper.getWritableDatabase();
db.insert( DBHelper.TABLE_NAME_INVITES, null, values );
db.close();
}
}
private static void setInt( long rowid, String column, int value ) private static void setInt( long rowid, String column, int value )
{ {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
@ -938,11 +1019,17 @@ public class DBUtils {
public static void deleteGame( Context context, GameLock lock ) public static void deleteGame( Context context, GameLock lock )
{ {
Assert.assertTrue( lock.canWrite() ); Assert.assertTrue( lock.canWrite() );
String selection = String.format( ROW_ID_FMT, lock.getRowid() ); String selSummaries = String.format( ROW_ID_FMT, lock.getRowid() );
String selInvites = String.format( "%s=%d", DBHelper.ROW, lock.getRowid() );
initDB( context ); initDB( context );
synchronized( s_dbHelper ) { synchronized( s_dbHelper ) {
SQLiteDatabase db = s_dbHelper.getWritableDatabase(); SQLiteDatabase db = s_dbHelper.getWritableDatabase();
db.delete( DBHelper.TABLE_NAME_SUM, selection, null ); db.delete( DBHelper.TABLE_NAME_SUM, selSummaries, null );
// Delete invitations too
db.delete( DBHelper.TABLE_NAME_INVITES, selInvites, null );
db.close(); db.close();
} }
notifyListeners( lock.getRowid(), GameChangeType.GAME_DELETED ); notifyListeners( lock.getRowid(), GameChangeType.GAME_DELETED );

View file

@ -138,6 +138,8 @@ public class DlgDelegate {
private static final String STATE_KEYF = "STATE_%d"; private static final String STATE_KEYF = "STATE_%d";
public interface DlgClickNotify { public interface DlgClickNotify {
// These are stored in the INVITES table. Don't change order
// gratuitously
public static enum InviteMeans { public static enum InviteMeans {
SMS, EMAIL, NFC, BLUETOOTH, CLIPBOARD, RELAY, SMS, EMAIL, NFC, BLUETOOTH, CLIPBOARD, RELAY,
}; };