diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
index 0422d75cb..0cb5f6c08 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/DlgID.java
@@ -52,9 +52,9 @@ public enum DlgID {
, REVERT_COLORS
, SET_DEFAULT
, SHOW_SUBST
- , WARN_NODICT
- , WARN_NODICT_NEW
- , WARN_NODICT_SUBST
+ , WARN_NODICT_GENERIC // the general trying-to-open case
+ , WARN_NODICT_INVITED // when responding to invitation
+ , WARN_NODICT_SUBST // when a substitution will be possible/suggested
, DLG_BADWORDS
, NOTIFY_BADWORDS
, QUERY_MOVE
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java
index e55198eac..d69c7d9a4 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GameUtils.java
@@ -407,8 +407,8 @@ public class GameUtils {
String[] dictNames = gi.dictNames();
DictUtils.DictPairs pairs = DictUtils.openDicts( context, dictNames );
if ( pairs.anyMissing( dictNames ) ) {
- Log.w( TAG, "loadMakeGame() failing: dicts %s unavailable",
- TextUtils.join( ",", dictNames ) );
+ postMoveDroppedForDictNotification( context, rowid, gi.gameID,
+ gi.dictLang );
} else {
String langName = gi.langName( context );
gamePtr = XwJNI.initFromStream( rowid, stream, gi, dictNames,
@@ -1264,6 +1264,18 @@ public class GameUtils {
}
}
+ private static void postMoveDroppedForDictNotification( Context context, long rowid,
+ int gameID, int lang )
+ {
+ Intent intent = GamesListDelegate.makeGameIDIntent( context, gameID );
+
+ String langName = DictLangCache.getLangName( context, lang );
+ String body = LocUtils.getString( context, R.string.no_dict_for_move_fmt,
+ langName );
+ Utils.postNotification( context, intent, R.string.no_dict_for_move_title,
+ body, rowid );
+ }
+
public static void postInvitedNotification( Context context, int gameID,
String body, long rowid )
{
diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
index dea70d82a..1c0e5b059 100644
--- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
+++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.java
@@ -637,14 +637,15 @@ public class GamesListDelegate extends ListDelegateBase
DlgID dlgID = alert.getDlgID();
switch ( dlgID ) {
- case WARN_NODICT:
- case WARN_NODICT_NEW:
+ case WARN_NODICT_GENERIC:
+ case WARN_NODICT_INVITED:
case WARN_NODICT_SUBST: {
final long rowid = (Long)params[0];
final String missingDictName = (String)params[1];
final int missingDictLang = (Integer)params[2];
lstnr = new OnClickListener() {
+ @Override
public void onClick( DialogInterface dlg, int item ) {
if ( null == missingDictName ) {
DictsDelegate
@@ -666,9 +667,9 @@ public class GamesListDelegate extends ListDelegateBase
DictLangCache.getLangName( m_activity, missingDictLang );
String locLang = xlateLang( langName );
String gameName = GameUtils.getName( m_activity, rowid );
- if ( DlgID.WARN_NODICT == dlgID ) {
+ if ( DlgID.WARN_NODICT_GENERIC == dlgID ) {
message = getString( R.string.no_dict_fmt, gameName, locLang );
- } else if ( DlgID.WARN_NODICT_NEW == dlgID ) {
+ } else if ( DlgID.WARN_NODICT_INVITED == dlgID ) {
message = getString( R.string.invite_dict_missing_body_noname_fmt,
null, missingDictName, locLang );
} else {
@@ -684,13 +685,23 @@ public class GamesListDelegate extends ListDelegateBase
.setNegativeButton( R.string.button_download, lstnr )
;
if ( DlgID.WARN_NODICT_SUBST == dlgID ) {
- lstnr = new OnClickListener() {
+ OnClickListener neuLstnr = new OnClickListener() {
+ @Override
public void onClick( DialogInterface dlg, int item ) {
showDialogFragment( DlgID.SHOW_SUBST, rowid,
missingDictName, missingDictLang );
}
};
- ab.setNeutralButton( R.string.button_substdict, lstnr );
+ ab.setNeutralButton( R.string.button_substdict, neuLstnr );
+ } else if ( DlgID.WARN_NODICT_GENERIC == dlgID ) {
+ OnClickListener neuLstnr = new OnClickListener() {
+ @Override
+ public void onClick( DialogInterface dlg, int item ) {
+ long[] rowids = {rowid};
+ deleteNamedIfConfirmed( rowids, false );
+ }
+ };
+ ab.setNeutralButton( R.string.button_delete, neuLstnr );
}
dialog = ab.create();
}
@@ -2255,7 +2266,7 @@ public class GamesListDelegate extends ListDelegateBase
}
if ( !haveDict ) {
m_netLaunchInfo = nli;
- showDialogFragment( DlgID.WARN_NODICT_NEW, 0L, nli.dict, nli.lang );
+ showDialogFragment( DlgID.WARN_NODICT_INVITED, 0L, nli.dict, nli.lang );
}
return haveDict;
}
@@ -2286,7 +2297,8 @@ public class GamesListDelegate extends ListDelegateBase
m_missingDictRowId = rowid;
m_missingDictMenuId = forMenu;
if ( 0 == DictLangCache.getLangCount( m_activity, missingDictLang ) ) {
- showDialogFragment( DlgID.WARN_NODICT, rowid, missingDictName, missingDictLang );
+ showDialogFragment( DlgID.WARN_NODICT_GENERIC, rowid,
+ missingDictName, missingDictLang );
} else if ( null != missingDictName ) {
showDialogFragment( DlgID.WARN_NODICT_SUBST, rowid, missingDictName,
missingDictLang );
@@ -2457,7 +2469,10 @@ public class GamesListDelegate extends ListDelegateBase
boolean handled = false;
long[] rowids = DBUtils.getRowIDsFor( m_activity, gameID );
if ( 0 < rowids.length ) {
- launchGame( rowids[0] );
+ long rowid = rowids[0];
+ if ( checkWarnNoDict( rowid ) ) {
+ launchGame( rowid );
+ }
handled = true;
}
return handled;
@@ -2674,16 +2689,34 @@ public class GamesListDelegate extends ListDelegateBase
}
}
- private void deleteIfConfirmed( long[] rowids, boolean skipTell )
+ private void mkDeleteAlert( String msg, long[] rowids, boolean skipTell )
{
- String msg = getQuantityString( R.plurals.confirm_seldeletes_fmt,
- rowids.length, rowids.length );
makeConfirmThenBuilder( msg, Action.DELETE_GAMES )
.setPosButton( R.string.button_delete )
.setParams( rowids, skipTell )
.show();
}
+ private void deleteIfConfirmed( long[] rowids, boolean skipTell )
+ {
+ String msg = getQuantityString( R.plurals.confirm_seldeletes_fmt,
+ rowids.length, rowids.length );
+ mkDeleteAlert( msg, rowids, skipTell );
+ }
+
+ private void deleteNamedIfConfirmed( long[] rowids, boolean skipTell )
+ {
+ String[] names = new String[rowids.length];
+ for ( int ii = 0; ii < rowids.length; ++ii ) {
+ names[ii] = DBUtils.getName( m_activity, rowids[ii] );
+ }
+ String namesStr = TextUtils.join( ", ", names );
+
+ String msg = getQuantityString( R.plurals.confirm_nameddeletes_fmt,
+ rowids.length, namesStr );
+ mkDeleteAlert( msg, rowids, skipTell );
+ }
+
private void deleteGames( long[] rowids, boolean skipTell )
{
for ( long rowid : rowids ) {
diff --git a/xwords4/android/app/src/main/res/values/strings.xml b/xwords4/android/app/src/main/res/values/strings.xml
index 54a630edc..756db0394 100644
--- a/xwords4/android/app/src/main/res/values/strings.xml
+++ b/xwords4/android/app/src/main/res/values/strings.xml
@@ -144,6 +144,16 @@
- Are you sure you want to delete
the %1$d selected games? This action cannot be undone.
+
+
+
+ - Are you sure you want to delete
+ the game %1$s? This action cannot be undone.
+ - Are you sure you want to delete
+ the games %1$s? This action cannot be undone.
+
@@ -1223,7 +1233,7 @@
takes wordlist name and language substituted in for %1$ and
%2$ -->
Game ā%1$sā requires a %2$s wordlist.
- Please download one before opening.
+ Please download one to open it.
@@ -1937,6 +1947,17 @@
too?
\u0020(You will have to download it
first.)
+
+
+ Incoming move lost
+
+ Tap to download %1$s wordlist
+ and recover
+
Reloading game with %1$s