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
you haven\'t already?</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 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 -->
<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
launched to send your invitation. -->
<string name="newgame_invite">Invite now</string>
<string name="newgame_invite_more">More info</string>
<string name="newgame_drop_relay">Drop Relay</string>
<!-- section separator (white-on-gray bar) for third section:
@ -2439,12 +2446,14 @@
<string name="waiting_title">Waiting for players</string>
<!-- 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="invite_stays">(This dialog will stay up until all
remote players have connected. You can close the game if you
expect it to take a while. They will still be able to
connect.)</string>
expect it to take a while. Remote players will still be able to
connect, and you will be notified when they do.)</string>
<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

View file

@ -464,6 +464,12 @@
sreyalp. Dluow uoy ekil ot etivni enoemos ot nioj -- gnimussa
uoy nevah\'t ?ydaerla</item>
</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 -->
<string name="invite_if_nfc">Ro tsuj Pat ot Etivni -- fi eht rehto
ecived osla sah Diordna Gnimaeb dna si ybraen.</string>
@ -1009,6 +1015,7 @@
it immediately because an email or messaging app will be
launched to send your invitation. -->
<string name="newgame_invite">Etivni won</string>
<string name="newgame_invite_more">Erom ofni</string>
<string name="newgame_drop_relay">Pord Yaler</string>
<!-- section separator (white-on-gray bar) for third section:
bluetooth games -->
@ -2091,11 +2098,13 @@
</string>
<string name="waiting_title">Gnitiaw rof sreyalp</string>
<!-- 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="invite_stays">sIht( golaid lliw yats pu litnu lla
etomer sreyalp evah detcennoc. Uoy nac esolc eht emag fi uoy
tcepxe ti ot ekat a elihw. Yeht lliw llits eb elba ot
tcennoc.)</string>
tcepxe ti ot ekat a elihw. Etomer sreyalp lliw llits eb elba ot
,tcennoc dna uoy lliw eb deifiton nehw yeht od.)</string>
<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
emag si nepo.</string>

View file

@ -464,6 +464,12 @@
PLAYERS. WOULD YOU LIKE TO INVITE SOMEONE TO JOIN -- ASSUMING
YOU HAVEN\'T ALREADY?</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 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 -->
<string name="invite_if_nfc">OR JUST TAP TO INVITE -- IF THE OTHER
DEVICE ALSO HAS ANDROID BEAMING AND IS NEARBY.</string>
@ -1009,6 +1015,7 @@
it immediately because an email or messaging app will be
launched to send your invitation. -->
<string name="newgame_invite">INVITE NOW</string>
<string name="newgame_invite_more">MORE INFO</string>
<string name="newgame_drop_relay">DROP RELAY</string>
<!-- section separator (white-on-gray bar) for third section:
bluetooth games -->
@ -2091,11 +2098,13 @@
</string>
<string name="waiting_title">WAITING FOR PLAYERS</string>
<!-- 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="invite_stays">(THIS DIALOG WILL STAY UP UNTIL ALL
REMOTE PLAYERS HAVE CONNECTED. YOU CAN CLOSE THE GAME IF YOU
EXPECT IT TO TAKE A WHILE. THEY WILL STILL BE ABLE TO
CONNECT.)</string>
EXPECT IT TO TAKE A WHILE. REMOTE PLAYERS WILL STILL BE ABLE TO
CONNECT, AND YOU WILL BE NOTIFIED WHEN THEY DO.)</string>
<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
GAME IS OPEN.</string>

View file

@ -96,6 +96,7 @@ public class BoardDelegate extends DelegateBase
private View m_tradeButtons;
private Button m_exchCommmitButton;
private Button m_exchCancelButton;
private DBUtils.SentInvitesInfo m_sentInfo;
private ArrayList<String> m_pendingChats;
@ -431,7 +432,15 @@ public class BoardDelegate extends DelegateBase
lstnr = new OnClickListener() {
public void onClick( DialogInterface dialog,
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) ) {
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION );
} else {
@ -504,21 +513,33 @@ public class BoardDelegate extends DelegateBase
buttonTxt = R.string.newgame_drop_relay;
}
} else {
titleID = R.string.waiting_title;
message = getQuantityString( R.plurals.invite_msg_fmt,
m_nMissing, m_nMissing );
String ps = null;
if ( m_nMissing > 1 ) {
ps = getString( R.string.invite_multiple );
m_sentInfo = DBUtils.getInvitesFor( m_activity, m_rowid );
int nSent = m_sentInfo.getPlayerCount();
boolean haveSent = nSent >= m_nMissing;
if ( haveSent ) {
titleID = R.string.waiting_invite_title;
message = getQuantityString( R.plurals.invite_sent_fmt,
nSent, nSent );
buttonTxt = R.string.newgame_invite_more;
} else {
boolean[] avail = NFCUtils.nfcAvail( m_activity );
if ( avail[1] ) {
ps = getString( R.string.invite_if_nfc );
}
titleID = R.string.waiting_title;
message = getQuantityString( R.plurals.invite_msg_fmt,
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 );
@ -2416,6 +2437,9 @@ public class BoardDelegate extends DelegateBase
}
break;
}
DBUtils.recordInviteSent( m_activity, m_rowid,
m_missingMeans, dev );
}
m_missingDevs = 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_LOC = "loc";
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 int DB_VERSION = 24;
private static final int DB_VERSION = 25;
public static final String GAME_NAME = "GAME_NAME";
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 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;
@ -194,6 +199,13 @@ public class DBHelper extends SQLiteOpenHelper {
,{ "UNIQUE", "(" + KEY + ")" }
};
private static final String[][] s_invitesSchema = {
{ ROW, "INTEGER" }
,{ TARGET, "TEXT" }
,{ MEANS, "INTEGER" }
,{ TIMESTAMP, "DATETIME DEFAULT CURRENT_TIMESTAMP" }
};
public DBHelper( Context context )
{
super( context, DB_NAME, null, DB_VERSION );
@ -217,6 +229,7 @@ public class DBHelper extends SQLiteOpenHelper {
createStudyTable( db );
createLocTable( db );
createPairsTable( db );
createInvitesTable( db );
}
@Override
@ -283,6 +296,9 @@ public class DBHelper extends SQLiteOpenHelper {
if ( !madeSumTable ) {
addSumColumn( db, EXTRAS );
}
case 24:
createInvitesTable( db );
break;
default:
db.execSQL( "DROP TABLE " + TABLE_NAME_SUM + ";" );
@ -381,6 +397,11 @@ public class DBHelper extends SQLiteOpenHelper {
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'
private void moveToCurGames( SQLiteDatabase db )
{

View file

@ -34,6 +34,8 @@ import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import java.sql.Timestamp;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
@ -52,10 +54,11 @@ import java.util.Set;
import java.util.StringTokenizer;
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.CommsAddrRec.CommsConnType;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.DictUtils.DictLoc;
import org.eehouse.android.xw4.loc.LocUtils;
public class DBUtils {
@ -426,6 +429,84 @@ public class DBUtils {
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 )
{
ContentValues values = new ContentValues();
@ -938,11 +1019,17 @@ public class DBUtils {
public static void deleteGame( Context context, GameLock lock )
{
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 );
synchronized( s_dbHelper ) {
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();
}
notifyListeners( lock.getRowid(), GameChangeType.GAME_DELETED );

View file

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