diff --git a/xwords4/android/XWords4/res/values/strings.xml b/xwords4/android/XWords4/res/values/strings.xml index d3b2b518a..319df69ee 100644 --- a/xwords4/android/XWords4/res/values/strings.xml +++ b/xwords4/android/XWords4/res/values/strings.xml @@ -62,6 +62,10 @@ Configure game Invite now Configure first + Are you sure you want to create + another game in room \"%s\"? Usually that happens when you open + an invitation message for the second time and isn\'t what you + want. Tap Ok to go ahead and create the second game. OK Cancel @@ -560,7 +564,7 @@ player[s]. Would you like to invite someone to join -- assuming you haven\'t already? Let\'s play Crosswords - Click on this link to start a game: + Tap on this link to start a game: %1$s. (If you don\'t have Crosswords: %2$s.) Send invitation via diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java index 47572b7ba..7215bde11 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardActivity.java @@ -324,7 +324,9 @@ public class BoardActivity extends XWActivity m_view = (BoardView)findViewById( R.id.board_view ); m_volKeysZoom = CommonPrefs.getVolKeysZoom( this ); - m_name = getIntent().getStringExtra( INTENT_KEY_NAME ); + Intent intent = getIntent(); + m_name = intent.getStringExtra( INTENT_KEY_NAME ); + m_haveInvited = intent.getBooleanExtra( GameUtils.INVITED, false ); setBackgroundColor(); } // onCreate @@ -700,7 +702,15 @@ public class BoardActivity extends XWActivity naKey = R.string.key_notagain_conndall; } } else if ( nMissing > 0 ) { - if ( m_haveInvited ) { + + // Let's only invite for two-person games for now. Simple + // case first.... + if ( nMissing == 1 /* && is_2_person_game() */ && !m_haveInvited ) { + m_haveInvited = true; + m_room = room; + m_missing = nMissing; + showDialog( DLG_INVITE ); + } else { String fmt = getString( R.string.msg_relay_waiting ); str = String.format( fmt, devOrder, room, nMissing ); @@ -711,11 +721,6 @@ public class BoardActivity extends XWActivity naMsg = R.string.not_again_conndmid; naKey = R.string.key_notagain_conndmid; } - } else { - m_haveInvited = true; - m_room = room; - m_missing = nMissing; - showDialog( DLG_INVITE ); } } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java index bd59ce199..b2a3ebbc8 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java @@ -350,6 +350,32 @@ public class DBUtils { return result; } + public static String getPathForOpen( Context context, String room, + // String inviteID, + int lang, int nPlayers ) + { + String result = null; + initDB( context ); + synchronized( s_dbHelper ) { + SQLiteDatabase db = s_dbHelper.getReadableDatabase(); + String[] columns = { DBHelper.FILE_NAME }; + String selection = DBHelper.ROOMNAME + "='" + room + "' AND " + // + DBHelper.INVITEID + "='" + inviteID + "' AND " + + DBHelper.DICTLANG + "=" + lang + " AND " + + DBHelper.NUM_PLAYERS + "=" + nPlayers; + Cursor cursor = db.query( DBHelper.TABLE_NAME_SUM, columns, + selection, null, null, null, null ); + if ( 1 == cursor.getCount() && cursor.moveToFirst() ) { + result = cursor.getString( cursor + .getColumnIndex(DBHelper.FILE_NAME)); + + } + cursor.close(); + db.close(); + } + return result; + } + public static String[] getRelayIDs( Context context, boolean noMsgs ) { String[] result = null; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java index 4d1981a04..79907ce79 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java @@ -36,6 +36,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.Lock; import java.util.HashMap; import java.util.HashSet; +import java.util.Random; import junit.framework.Assert; @@ -45,6 +46,7 @@ import org.eehouse.android.xw4.jni.CurGameInfo.DeviceRole; public class GameUtils { public enum DictLoc { BUILT_IN, INTERNAL, EXTERNAL, DOWNLOAD }; + public static final String INVITED = "invited"; // Implements read-locks and write-locks per game. A read lock is // obtainable when other read locks are granted but not when a @@ -374,17 +376,27 @@ public class GameUtils { return path; } + public static String makeNewNetGame( Context context, String room, + int lang, int nPlayers ) + { + int[] langarr = { lang }; + return makeNewNetGame( context, room, langarr, nPlayers ); + } + public static void launchInviteActivity( Context context, String room, int lang ) { Intent intent = new Intent( Intent.ACTION_SEND ); - intent.setType( "plain/text" ); + intent.setType( "text/plain" ); intent.putExtra( Intent.EXTRA_SUBJECT, context.getString( R.string.invite_subject ) ); String format = context.getString( R.string.game_urlf ); String host = CommonPrefs.getDefaultRelayHost( context ); - String gameUrl = String.format( format, host, room, lang ); + Random random = new Random(); + String inviteID = + String.format( "%x", random.nextInt() ).substring( 0, 4 ); + String gameUrl = String.format( format, host, room, lang, inviteID ); format = context.getString( R.string.invite_bodyf ); String appUrl = context.getString( R.string.app_market_url ); String message = String.format( format, gameUrl, appUrl ); @@ -724,14 +736,23 @@ public class GameUtils { return path.substring( 0, path.lastIndexOf( XWConstants.GAME_EXTN ) ); } - public static void launchGame( Activity activity, String path ) + public static void launchGame( Activity activity, String path, + boolean invited ) { Intent intent = new Intent( activity, BoardActivity.class ); intent.setAction( Intent.ACTION_EDIT ); intent.putExtra( BoardActivity.INTENT_KEY_NAME, path ); + if ( invited ) { + intent.putExtra( INVITED, true ); + } activity.startActivity( intent ); } + public static void launchGame( Activity activity, String path ) + { + launchGame( activity, path, false ); + } + public static void launchGameAndFinish( Activity activity, String path ) { launchGame( activity, path ); diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java index 2a3936715..4bbdf6a91 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GamesList.java @@ -28,6 +28,7 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.DialogInterface; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.view.ContextMenu; @@ -545,11 +546,12 @@ public class GamesList extends XWListActivity if ( null != intent ) { Uri data = intent.getData(); if ( null != data ) { - String room = data.getQueryParameter( "room" ); + final String room = data.getQueryParameter( "room" ); String langStr = data.getQueryParameter( "lang" ); - int lang = Integer.decode( langStr ); - int nPlayers = 2; // Should this be a param? - Utils.logf( "got data: lang: %d; room: %s", lang, room ); + final int lang = Integer.decode( langStr ); + final int nPlayers = 2; // Should this be a param? + Utils.logf( "got data: lang: %d; room: %s", + lang, room ); // Find out if the game already exists. If it does, // just open it. Otherwise create a new one and open @@ -558,16 +560,35 @@ public class GamesList extends XWListActivity // this feature. But it'd be worse to have a bunch of // games stacking up when somebody taps the same URL // multiple times. - String path = null;// (for now; should be: DBUtils.getPathForOpen( this, room, lang, nPlayers ); + + // No. If the game already exists, warn the user, but + // give him choice to open new or existing game. + + String path = + DBUtils.getPathForOpen( this, room, lang, nPlayers ); + + if ( null == path ) { - int[] langarr = { lang }; - path = GameUtils.makeNewNetGame( this, room, langarr, - nPlayers ); + path = GameUtils.makeNewNetGame( this, room, lang, + nPlayers ); + GameUtils.launchGame( this, path, true ); + } else { + DialogInterface.OnClickListener then = + new DialogInterface.OnClickListener() { + public void onClick( DialogInterface dlg, int ii ) { + String path = + GameUtils.makeNewNetGame( GamesList.this, + room, lang, + nPlayers ); + GameUtils.launchGame( GamesList.this, path, true ); + } + }; + String fmt = getString( R.string.dup_game_queryf ); + String msg = String.format( fmt, room ); + showConfirmThen( msg, then ); } - - GameUtils.launchGame( this, path ); } } - } + } // startNewNetGameIf } diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java index 3928eea6f..d63d8200d 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/NewGameActivity.java @@ -91,15 +91,16 @@ public class NewGameActivity extends XWActivity { private void newNetworkedAndLaunch() { Random random = new Random(); - String room = String.format( "%X", random.nextInt() ); + String room = + String.format( "%X", random.nextInt() ).substring( 0, 4 ); int[] lang = {0}; String path = GameUtils.makeNewNetGame( this, room, lang, 2 ); - GameUtils.launchGame( this, path ); + GameUtils.launchGame( this, path, true ); // Remove this for now at least. The game itself will suggest // an invite when it connects and is missing someone. - // GameUtils.launchInviteActivity( this, room, lang[0] ); + GameUtils.launchInviteActivity( this, room, lang[0] ); finish(); }