diff --git a/xwords4/android/XWords4-dbg/AndroidManifest.xml b/xwords4/android/XWords4-dbg/AndroidManifest.xml
index aa14745ce..a59ab8e0a 100644
--- a/xwords4/android/XWords4-dbg/AndroidManifest.xml
+++ b/xwords4/android/XWords4-dbg/AndroidManifest.xml
@@ -1,20 +1,4 @@
-
-
-
diff --git a/xwords4/android/XWords4-dbg/res/layout/.gitignore b/xwords4/android/XWords4-dbg/res/layout/.gitignore
index d98ed5c93..33834f82c 100644
--- a/xwords4/android/XWords4-dbg/res/layout/.gitignore
+++ b/xwords4/android/XWords4-dbg/res/layout/.gitignore
@@ -44,3 +44,4 @@ not_again_view.xml
relayinviter.xml
remote_dict_details.xml
toolbar.xml
+chat_row.xml
diff --git a/xwords4/android/XWords4/archive/R.java b/xwords4/android/XWords4/archive/R.java
index 9c11a297c..5b8e15bb1 100644
--- a/xwords4/android/XWords4/archive/R.java
+++ b/xwords4/android/XWords4/archive/R.java
@@ -83,212 +83,214 @@ public final class R {
}
public static final class id {
public static final int about_xlator=0x7f0a0001;
- public static final int add_player=0x7f0a0030;
- public static final int advertise_new_room_check=0x7f0a0037;
- public static final int blessed_label=0x7f0a0057;
- public static final int board_menu_chat=0x7f0a00a0;
- public static final int board_menu_dict=0x7f0a009c;
- public static final int board_menu_done=0x7f0a0086;
- public static final int board_menu_file_prefs=0x7f0a0093;
- public static final int board_menu_flip=0x7f0a009e;
- public static final int board_menu_game_counts=0x7f0a008c;
- public static final int board_menu_game_history=0x7f0a008e;
- public static final int board_menu_game_invites=0x7f0a0095;
- public static final int board_menu_game_left=0x7f0a008d;
- public static final int board_menu_game_netstats=0x7f0a0094;
- public static final int board_menu_game_resend=0x7f0a0090;
- public static final int board_menu_game_resign=0x7f0a008f;
- public static final int board_menu_hint_next=0x7f0a009a;
- public static final int board_menu_hint_prev=0x7f0a0099;
- public static final int board_menu_invite=0x7f0a0096;
- public static final int board_menu_juggle=0x7f0a009d;
- public static final int board_menu_rematch=0x7f0a0085;
- public static final int board_menu_toggle=0x7f0a00a1;
- public static final int board_menu_trade=0x7f0a0087;
- public static final int board_menu_trade_cancel=0x7f0a0088;
- public static final int board_menu_trade_commit=0x7f0a0089;
- public static final int board_menu_tray=0x7f0a008b;
- public static final int board_menu_undo_current=0x7f0a009b;
- public static final int board_menu_undo_last=0x7f0a008a;
- public static final int board_menu_zoom=0x7f0a009f;
+ public static final int add_player=0x7f0a0032;
+ public static final int advertise_new_room_check=0x7f0a0039;
+ public static final int blessed_label=0x7f0a0059;
+ public static final int board_menu_chat=0x7f0a00a2;
+ public static final int board_menu_dict=0x7f0a009e;
+ public static final int board_menu_done=0x7f0a0088;
+ public static final int board_menu_file_prefs=0x7f0a0095;
+ public static final int board_menu_flip=0x7f0a00a0;
+ public static final int board_menu_game_counts=0x7f0a008e;
+ public static final int board_menu_game_history=0x7f0a0090;
+ public static final int board_menu_game_invites=0x7f0a0097;
+ public static final int board_menu_game_left=0x7f0a008f;
+ public static final int board_menu_game_netstats=0x7f0a0096;
+ public static final int board_menu_game_resend=0x7f0a0092;
+ public static final int board_menu_game_resign=0x7f0a0091;
+ public static final int board_menu_hint_next=0x7f0a009c;
+ public static final int board_menu_hint_prev=0x7f0a009b;
+ public static final int board_menu_invite=0x7f0a0098;
+ public static final int board_menu_juggle=0x7f0a009f;
+ public static final int board_menu_rematch=0x7f0a0087;
+ public static final int board_menu_toggle=0x7f0a00a3;
+ public static final int board_menu_trade=0x7f0a0089;
+ public static final int board_menu_trade_cancel=0x7f0a008a;
+ public static final int board_menu_trade_commit=0x7f0a008b;
+ public static final int board_menu_tray=0x7f0a008d;
+ public static final int board_menu_undo_current=0x7f0a009d;
+ public static final int board_menu_undo_last=0x7f0a008c;
+ public static final int board_menu_zoom=0x7f0a00a1;
public static final int board_root=0x7f0a0002;
public static final int board_view=0x7f0a0003;
- public static final int boardsize_spinner=0x7f0a0043;
- public static final int button_add=0x7f0a0071;
+ public static final int boardsize_spinner=0x7f0a0045;
+ public static final int button_add=0x7f0a0073;
public static final int button_clear=0x7f0a000b;
- public static final int button_done=0x7f0a0062;
+ public static final int button_done=0x7f0a0064;
public static final int button_invite=0x7f0a000c;
- public static final int button_newgame_multi=0x7f0a0045;
- public static final int button_newgame_solo=0x7f0a0044;
+ public static final int button_newgame_multi=0x7f0a0047;
+ public static final int button_newgame_solo=0x7f0a0046;
public static final int button_rescan=0x7f0a000a;
- public static final int button_study=0x7f0a0061;
- public static final int change_connection=0x7f0a003b;
- public static final int chat_button=0x7f0a0080;
+ public static final int button_study=0x7f0a0063;
+ public static final int change_connection=0x7f0a003d;
+ public static final int chat_button=0x7f0a0082;
public static final int chat_edit=0x7f0a0011;
public static final int chat_history=0x7f0a0010;
- public static final int chat_menu_clear=0x7f0a00a3;
- public static final int chat_menu_send=0x7f0a00a2;
- public static final int checkbox=0x7f0a0051;
- public static final int color_display_sample=0x7f0a0012;
- public static final int color_edit_sample=0x7f0a0013;
- public static final int confirm_sms_reasons=0x7f0a001a;
- public static final int conn_types=0x7f0a001b;
- public static final int connect_set_relay=0x7f0a0033;
- public static final int conns_label=0x7f0a0032;
- public static final int default_check=0x7f0a001c;
- public static final int del=0x7f0a0054;
- public static final int desc=0x7f0a001f;
- public static final int details=0x7f0a0072;
- public static final int dict_label=0x7f0a0069;
- public static final int dict_spinner=0x7f0a002d;
- public static final int dictlist_button=0x7f0a007f;
- public static final int dicts_delete=0x7f0a00a6;
- public static final int dicts_deselect_all=0x7f0a00a5;
- public static final int dicts_download=0x7f0a00a4;
- public static final int dicts_move=0x7f0a00a7;
- public static final int dicts_select=0x7f0a00a8;
- public static final int divider=0x7f0a0024;
- public static final int download_button=0x7f0a0073;
- public static final int dwnld_message=0x7f0a004f;
- public static final int edit=0x7f0a0063;
- public static final int edit_blue=0x7f0a0019;
- public static final int edit_green=0x7f0a0017;
- public static final int edit_red=0x7f0a0015;
- public static final int english_label=0x7f0a0055;
- public static final int english_view=0x7f0a0056;
+ public static final int chat_menu_clear=0x7f0a00a5;
+ public static final int chat_menu_send=0x7f0a00a4;
+ public static final int chat_row_name=0x7f0a0012;
+ public static final int chat_row_text=0x7f0a0013;
+ public static final int checkbox=0x7f0a0053;
+ public static final int color_display_sample=0x7f0a0014;
+ public static final int color_edit_sample=0x7f0a0015;
+ public static final int confirm_sms_reasons=0x7f0a001c;
+ public static final int conn_types=0x7f0a001d;
+ public static final int connect_set_relay=0x7f0a0035;
+ public static final int conns_label=0x7f0a0034;
+ public static final int default_check=0x7f0a001e;
+ public static final int del=0x7f0a0056;
+ public static final int desc=0x7f0a0021;
+ public static final int details=0x7f0a0074;
+ public static final int dict_label=0x7f0a006b;
+ public static final int dict_spinner=0x7f0a002f;
+ public static final int dictlist_button=0x7f0a0081;
+ public static final int dicts_delete=0x7f0a00a8;
+ public static final int dicts_deselect_all=0x7f0a00a7;
+ public static final int dicts_download=0x7f0a00a6;
+ public static final int dicts_move=0x7f0a00a9;
+ public static final int dicts_select=0x7f0a00aa;
+ public static final int divider=0x7f0a0026;
+ public static final int download_button=0x7f0a0075;
+ public static final int dwnld_message=0x7f0a0051;
+ public static final int edit=0x7f0a0065;
+ public static final int edit_blue=0x7f0a001b;
+ public static final int edit_green=0x7f0a0019;
+ public static final int edit_red=0x7f0a0017;
+ public static final int english_label=0x7f0a0057;
+ public static final int english_view=0x7f0a0058;
public static final int exchange_buttons=0x7f0a0004;
public static final int exchange_cancel=0x7f0a0006;
public static final int exchange_commit=0x7f0a0005;
- public static final int expander=0x7f0a0026;
- public static final int filters=0x7f0a005c;
- public static final int flip_button=0x7f0a0082;
- public static final int game_locked_check=0x7f0a0028;
- public static final int game_name=0x7f0a0046;
- public static final int gamel_menu_checkmoves=0x7f0a0092;
- public static final int games_game_config=0x7f0a00ab;
- public static final int games_game_copy=0x7f0a00b0;
- public static final int games_game_delete=0x7f0a00a9;
- public static final int games_game_deselect=0x7f0a00b2;
- public static final int games_game_invites=0x7f0a00b3;
- public static final int games_game_move=0x7f0a00ac;
- public static final int games_game_new_from=0x7f0a00ae;
- public static final int games_game_rematch=0x7f0a00aa;
- public static final int games_game_rename=0x7f0a00af;
- public static final int games_game_reset=0x7f0a00ad;
- public static final int games_game_select=0x7f0a00b1;
- public static final int games_group_default=0x7f0a00b7;
- public static final int games_group_delete=0x7f0a00b6;
- public static final int games_group_movedown=0x7f0a00b5;
- public static final int games_group_moveup=0x7f0a00b4;
- public static final int games_group_rename=0x7f0a00b8;
- public static final int games_menu_about=0x7f0a00c0;
- public static final int games_menu_checkmoves=0x7f0a00c2;
- public static final int games_menu_checkupdates=0x7f0a00c3;
- public static final int games_menu_dicts=0x7f0a00be;
- public static final int games_menu_email=0x7f0a00bf;
- public static final int games_menu_loaddb=0x7f0a00c5;
- public static final int games_menu_newgame_net=0x7f0a00ba;
- public static final int games_menu_newgame_solo=0x7f0a00b9;
- public static final int games_menu_newgroup=0x7f0a00bb;
- public static final int games_menu_prefs=0x7f0a00bc;
- public static final int games_menu_rateme=0x7f0a00bd;
- public static final int games_menu_resend=0x7f0a00c1;
- public static final int games_menu_storedb=0x7f0a00c4;
- public static final int games_menu_study=0x7f0a0091;
- public static final int group_done=0x7f0a0084;
- public static final int group_exchange=0x7f0a0097;
- public static final int group_hint=0x7f0a0098;
- public static final int hideable=0x7f0a004b;
- public static final int hints_allowed=0x7f0a003c;
+ public static final int expander=0x7f0a0028;
+ public static final int filters=0x7f0a005e;
+ public static final int flip_button=0x7f0a0084;
+ public static final int game_locked_check=0x7f0a002a;
+ public static final int game_name=0x7f0a0048;
+ public static final int gamel_menu_checkmoves=0x7f0a0094;
+ public static final int games_game_config=0x7f0a00ad;
+ public static final int games_game_copy=0x7f0a00b2;
+ public static final int games_game_delete=0x7f0a00ab;
+ public static final int games_game_deselect=0x7f0a00b4;
+ public static final int games_game_invites=0x7f0a00b5;
+ public static final int games_game_move=0x7f0a00ae;
+ public static final int games_game_new_from=0x7f0a00b0;
+ public static final int games_game_rematch=0x7f0a00ac;
+ public static final int games_game_rename=0x7f0a00b1;
+ public static final int games_game_reset=0x7f0a00af;
+ public static final int games_game_select=0x7f0a00b3;
+ public static final int games_group_default=0x7f0a00b9;
+ public static final int games_group_delete=0x7f0a00b8;
+ public static final int games_group_movedown=0x7f0a00b7;
+ public static final int games_group_moveup=0x7f0a00b6;
+ public static final int games_group_rename=0x7f0a00ba;
+ public static final int games_menu_about=0x7f0a00c2;
+ public static final int games_menu_checkmoves=0x7f0a00c4;
+ public static final int games_menu_checkupdates=0x7f0a00c5;
+ public static final int games_menu_dicts=0x7f0a00c0;
+ public static final int games_menu_email=0x7f0a00c1;
+ public static final int games_menu_loaddb=0x7f0a00c7;
+ public static final int games_menu_newgame_net=0x7f0a00bc;
+ public static final int games_menu_newgame_solo=0x7f0a00bb;
+ public static final int games_menu_newgroup=0x7f0a00bd;
+ public static final int games_menu_prefs=0x7f0a00be;
+ public static final int games_menu_rateme=0x7f0a00bf;
+ public static final int games_menu_resend=0x7f0a00c3;
+ public static final int games_menu_storedb=0x7f0a00c6;
+ public static final int games_menu_study=0x7f0a0093;
+ public static final int group_done=0x7f0a0086;
+ public static final int group_exchange=0x7f0a0099;
+ public static final int group_hint=0x7f0a009a;
+ public static final int hideable=0x7f0a004d;
+ public static final int hints_allowed=0x7f0a003e;
public static final int invite_desc=0x7f0a0009;
public static final int inviter_check=0x7f0a000d;
- public static final int item_name=0x7f0a006d;
- public static final int item_score=0x7f0a006e;
- public static final int join_public_room_check=0x7f0a0034;
- public static final int juggle_players=0x7f0a0031;
- public static final int label=0x7f0a0025;
- public static final int lang_separator=0x7f0a002b;
- public static final int lang_spinner=0x7f0a002c;
- public static final int loc_item_check=0x7f0a00c7;
- public static final int loc_item_clear=0x7f0a00c6;
- public static final int loc_item_copy_bless=0x7f0a00c9;
- public static final int loc_item_copy_eng=0x7f0a00c8;
- public static final int loc_search_button=0x7f0a005e;
- public static final int loc_search_field=0x7f0a005d;
- public static final int local_label=0x7f0a0059;
- public static final int local_player_set=0x7f0a0067;
- public static final int manual_add_button=0x7f0a0075;
- public static final int modtime=0x7f0a004c;
- public static final int msg=0x7f0a0064;
- public static final int msg_marker=0x7f0a0049;
- public static final int name=0x7f0a0076;
- public static final int name_edit=0x7f0a001d;
- public static final int name_label=0x7f0a0074;
- public static final int nexthint_button=0x7f0a007c;
- public static final int not_again_check=0x7f0a0065;
+ public static final int item_name=0x7f0a006f;
+ public static final int item_score=0x7f0a0070;
+ public static final int join_public_room_check=0x7f0a0036;
+ public static final int juggle_players=0x7f0a0033;
+ public static final int label=0x7f0a0027;
+ public static final int lang_separator=0x7f0a002d;
+ public static final int lang_spinner=0x7f0a002e;
+ public static final int loc_item_check=0x7f0a00c9;
+ public static final int loc_item_clear=0x7f0a00c8;
+ public static final int loc_item_copy_bless=0x7f0a00cb;
+ public static final int loc_item_copy_eng=0x7f0a00ca;
+ public static final int loc_search_button=0x7f0a0060;
+ public static final int loc_search_field=0x7f0a005f;
+ public static final int local_label=0x7f0a005b;
+ public static final int local_player_set=0x7f0a0069;
+ public static final int manual_add_button=0x7f0a0077;
+ public static final int modtime=0x7f0a004e;
+ public static final int msg=0x7f0a0066;
+ public static final int msg_marker=0x7f0a004b;
+ public static final int name=0x7f0a0078;
+ public static final int name_edit=0x7f0a001f;
+ public static final int name_label=0x7f0a0076;
+ public static final int nexthint_button=0x7f0a007e;
+ public static final int not_again_check=0x7f0a0067;
public static final int nperdev_spinner=0x7f0a000e;
- public static final int number=0x7f0a0077;
- public static final int other_lang=0x7f0a005f;
- public static final int password_edit=0x7f0a006c;
- public static final int password_set=0x7f0a006b;
- public static final int phonies_spinner=0x7f0a0041;
- public static final int pick_faceup=0x7f0a0042;
- public static final int pick_lang=0x7f0a0078;
- public static final int pick_lang_spinner=0x7f0a0079;
- public static final int play_button=0x7f0a0029;
- public static final int player_list=0x7f0a002f;
- public static final int player_name_edit=0x7f0a0068;
- public static final int players=0x7f0a0027;
- public static final int players_label=0x7f0a002e;
- public static final int prevhint_button=0x7f0a007b;
- public static final int private_rooms_set=0x7f0a0035;
- public static final int progress_bar=0x7f0a0050;
- public static final int public_rooms_set=0x7f0a0038;
- public static final int refresh_button=0x7f0a003a;
- public static final int remote_check=0x7f0a0066;
- public static final int revert_all=0x7f0a0070;
- public static final int revert_colors=0x7f0a006f;
- public static final int robot_check=0x7f0a006a;
- public static final int role=0x7f0a004e;
- public static final int room_edit=0x7f0a0036;
- public static final int room_spinner=0x7f0a0039;
- public static final int screen=0x7f0a002a;
+ public static final int number=0x7f0a0079;
+ public static final int other_lang=0x7f0a0061;
+ public static final int password_edit=0x7f0a006e;
+ public static final int password_set=0x7f0a006d;
+ public static final int phonies_spinner=0x7f0a0043;
+ public static final int pick_faceup=0x7f0a0044;
+ public static final int pick_lang=0x7f0a007a;
+ public static final int pick_lang_spinner=0x7f0a007b;
+ public static final int play_button=0x7f0a002b;
+ public static final int player_list=0x7f0a0031;
+ public static final int player_name_edit=0x7f0a006a;
+ public static final int players=0x7f0a0029;
+ public static final int players_label=0x7f0a0030;
+ public static final int prevhint_button=0x7f0a007d;
+ public static final int private_rooms_set=0x7f0a0037;
+ public static final int progress_bar=0x7f0a0052;
+ public static final int public_rooms_set=0x7f0a003a;
+ public static final int refresh_button=0x7f0a003c;
+ public static final int remote_check=0x7f0a0068;
+ public static final int revert_all=0x7f0a0072;
+ public static final int revert_colors=0x7f0a0071;
+ public static final int robot_check=0x7f0a006c;
+ public static final int role=0x7f0a0050;
+ public static final int room_edit=0x7f0a0038;
+ public static final int room_spinner=0x7f0a003b;
+ public static final int screen=0x7f0a002c;
public static final int scroll=0x7f0a000f;
- public static final int search_button=0x7f0a0021;
- public static final int seek_blue=0x7f0a0018;
- public static final int seek_green=0x7f0a0016;
- public static final int seek_red=0x7f0a0014;
- public static final int show_remote=0x7f0a001e;
- public static final int shuffle_button=0x7f0a007d;
- public static final int slmenu_clear_sel=0x7f0a00ce;
- public static final int slmenu_copy_sel=0x7f0a00cd;
- public static final int slmenu_deselect_all=0x7f0a00cc;
- public static final int slmenu_lookup_sel=0x7f0a00ca;
- public static final int slmenu_select_all=0x7f0a00cb;
- public static final int smart_robot=0x7f0a0040;
- public static final int state=0x7f0a004d;
- public static final int summary=0x7f0a0060;
+ public static final int search_button=0x7f0a0023;
+ public static final int seek_blue=0x7f0a001a;
+ public static final int seek_green=0x7f0a0018;
+ public static final int seek_red=0x7f0a0016;
+ public static final int show_remote=0x7f0a0020;
+ public static final int shuffle_button=0x7f0a007f;
+ public static final int slmenu_clear_sel=0x7f0a00d0;
+ public static final int slmenu_copy_sel=0x7f0a00cf;
+ public static final int slmenu_deselect_all=0x7f0a00ce;
+ public static final int slmenu_lookup_sel=0x7f0a00cc;
+ public static final int slmenu_select_all=0x7f0a00cd;
+ public static final int smart_robot=0x7f0a0042;
+ public static final int state=0x7f0a004f;
+ public static final int summary=0x7f0a0062;
public static final int tbar_parent_hor=0x7f0a0007;
public static final int tbar_parent_vert=0x7f0a0008;
- public static final int text_item=0x7f0a0052;
- public static final int text_item2=0x7f0a0053;
- public static final int thumbnail=0x7f0a004a;
- public static final int timer_minutes_edit=0x7f0a003f;
- public static final int timer_set=0x7f0a003e;
- public static final int toolbar=0x7f0a007a;
- public static final int undo_button=0x7f0a007e;
- public static final int use_timer=0x7f0a003d;
- public static final int values_button=0x7f0a0081;
+ public static final int text_item=0x7f0a0054;
+ public static final int text_item2=0x7f0a0055;
+ public static final int thumbnail=0x7f0a004c;
+ public static final int timer_minutes_edit=0x7f0a0041;
+ public static final int timer_set=0x7f0a0040;
+ public static final int toolbar=0x7f0a007c;
+ public static final int undo_button=0x7f0a0080;
+ public static final int use_timer=0x7f0a003f;
+ public static final int values_button=0x7f0a0083;
public static final int version_string=0x7f0a0000;
- public static final int view_loaded=0x7f0a0048;
- public static final int view_unloaded=0x7f0a0047;
- public static final int word_edit=0x7f0a0020;
- public static final int wordlen_max=0x7f0a0023;
- public static final int wordlen_min=0x7f0a0022;
- public static final int xlated_view=0x7f0a005b;
- public static final int xlated_view_blessed=0x7f0a0058;
- public static final int xlated_view_local=0x7f0a005a;
- public static final int zoom_button=0x7f0a0083;
+ public static final int view_loaded=0x7f0a004a;
+ public static final int view_unloaded=0x7f0a0049;
+ public static final int word_edit=0x7f0a0022;
+ public static final int wordlen_max=0x7f0a0025;
+ public static final int wordlen_min=0x7f0a0024;
+ public static final int xlated_view=0x7f0a005d;
+ public static final int xlated_view_blessed=0x7f0a005a;
+ public static final int xlated_view_local=0x7f0a005c;
+ public static final int zoom_button=0x7f0a0085;
}
public static final class layout {
public static final int about_dlg=0x7f030000;
@@ -296,43 +298,42 @@ public final class R {
public static final int btinviter=0x7f030002;
public static final int btinviter_item=0x7f030003;
public static final int chat=0x7f030004;
- public static final int chat_history_local=0x7f030005;
- public static final int chat_history_remote=0x7f030006;
- public static final int color_display=0x7f030007;
- public static final int color_edit=0x7f030008;
- public static final int confirm_sms=0x7f030009;
- public static final int conn_types_display=0x7f03000a;
- public static final int dflt_name=0x7f03000b;
- public static final int dict_browse=0x7f03000c;
- public static final int dict_browser=0x7f03000d;
- public static final int divider_view=0x7f03000e;
- public static final int expander_header=0x7f03000f;
- public static final int force_remote=0x7f030010;
- public static final int game_config=0x7f030011;
- public static final int game_list=0x7f030012;
- public static final int game_list_group=0x7f030013;
- public static final int game_list_item=0x7f030014;
- public static final int import_dict=0x7f030015;
- public static final int import_dict_item=0x7f030016;
- public static final int list_group=0x7f030017;
- public static final int list_item=0x7f030018;
- public static final int loc_item_edit=0x7f030019;
- public static final int loc_list_item=0x7f03001a;
- public static final int loc_main=0x7f03001b;
- public static final int lookup=0x7f03001c;
- public static final int msg_label_and_edit=0x7f03001d;
- public static final int not_again_view=0x7f03001e;
- public static final int passwd_view=0x7f03001f;
- public static final int player_edit=0x7f030020;
- public static final int player_list_elem=0x7f030021;
- public static final int prefs_w_buttons=0x7f030022;
- public static final int relayinviter=0x7f030023;
- public static final int remote_dict_details=0x7f030024;
- public static final int rename_game=0x7f030025;
- public static final int smsinviter=0x7f030026;
- public static final int smsinviter_item=0x7f030027;
- public static final int studylist=0x7f030028;
- public static final int toolbar=0x7f030029;
+ public static final int chat_row=0x7f030005;
+ public static final int color_display=0x7f030006;
+ public static final int color_edit=0x7f030007;
+ public static final int confirm_sms=0x7f030008;
+ public static final int conn_types_display=0x7f030009;
+ public static final int dflt_name=0x7f03000a;
+ public static final int dict_browse=0x7f03000b;
+ public static final int dict_browser=0x7f03000c;
+ public static final int divider_view=0x7f03000d;
+ public static final int expander_header=0x7f03000e;
+ public static final int force_remote=0x7f03000f;
+ public static final int game_config=0x7f030010;
+ public static final int game_list=0x7f030011;
+ public static final int game_list_group=0x7f030012;
+ public static final int game_list_item=0x7f030013;
+ public static final int import_dict=0x7f030014;
+ public static final int import_dict_item=0x7f030015;
+ public static final int list_group=0x7f030016;
+ public static final int list_item=0x7f030017;
+ public static final int loc_item_edit=0x7f030018;
+ public static final int loc_list_item=0x7f030019;
+ public static final int loc_main=0x7f03001a;
+ public static final int lookup=0x7f03001b;
+ public static final int msg_label_and_edit=0x7f03001c;
+ public static final int not_again_view=0x7f03001d;
+ public static final int passwd_view=0x7f03001e;
+ public static final int player_edit=0x7f03001f;
+ public static final int player_list_elem=0x7f030020;
+ public static final int prefs_w_buttons=0x7f030021;
+ public static final int relayinviter=0x7f030022;
+ public static final int remote_dict_details=0x7f030023;
+ public static final int rename_game=0x7f030024;
+ public static final int smsinviter=0x7f030025;
+ public static final int smsinviter_item=0x7f030026;
+ public static final int studylist=0x7f030027;
+ public static final int toolbar=0x7f030028;
}
public static final class menu {
public static final int board_menu=0x7f090000;
diff --git a/xwords4/android/XWords4/jni/utilwrapper.c b/xwords4/android/XWords4/jni/utilwrapper.c
index be8a093cb..2124ffd01 100644
--- a/xwords4/android/XWords4/jni/utilwrapper.c
+++ b/xwords4/android/XWords4/jni/utilwrapper.c
@@ -503,7 +503,7 @@ and_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
static void
and_util_showChat( XW_UtilCtxt* uc, const XP_UCHAR const* msg, XP_S16 from )
{
- UTIL_CBK_HEADER( "showChat", "(Ljava/lang/String;Ljava/lang/String;)V" );
+ UTIL_CBK_HEADER( "showChat", "(Ljava/lang/String;ILjava/lang/String;)V" );
jstring jname = NULL;
if ( 0 <= from ) {
LocalPlayer* lp = &uc->gameInfo->players[from];
@@ -512,7 +512,7 @@ and_util_showChat( XW_UtilCtxt* uc, const XP_UCHAR const* msg, XP_S16 from )
}
jstring jmsg = (*env)->NewStringUTF( env, msg );
- (*env)->CallVoidMethod( env, util->jutil, mid, jmsg, jname );
+ (*env)->CallVoidMethod( env, util->jutil, mid, jmsg, from, jname );
deleteLocalRefs( env, jmsg, jname, DELETE_NO_REF );
UTIL_CBK_TAIL();
}
diff --git a/xwords4/android/XWords4/jni/xwjni.c b/xwords4/android/XWords4/jni/xwjni.c
index 301f7f937..831a72f77 100644
--- a/xwords4/android/XWords4/jni/xwjni.c
+++ b/xwords4/android/XWords4/jni/xwjni.c
@@ -1127,6 +1127,17 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getTrayVisState
return result;
}
+JNIEXPORT jint JNICALL
+Java_org_eehouse_android_xw4_jni_XwJNI_board_1getSelPlayer
+(JNIEnv* env, jclass C, GamePtrType gamePtr)
+{
+ jint result;
+ XWJNI_START();
+ result = board_getSelPlayer( state->game.board );
+ XWJNI_END();
+ return result;
+}
+
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1hideTray
(JNIEnv* env, jclass C, GamePtrType gamePtr)
diff --git a/xwords4/android/XWords4/res/layout/chat.xml b/xwords4/android/XWords4/res/layout/chat.xml
index 422ccfcd7..4dba35872 100644
--- a/xwords4/android/XWords4/res/layout/chat.xml
+++ b/xwords4/android/XWords4/res/layout/chat.xml
@@ -6,20 +6,19 @@
android:layout_height="fill_parent"
>
-
-
+
+
+
+
-
-
diff --git a/xwords4/android/XWords4/res/layout/chat_history_remote.xml b/xwords4/android/XWords4/res/layout/chat_history_remote.xml
deleted file mode 100644
index 2b3cce0ee..000000000
--- a/xwords4/android/XWords4/res/layout/chat_history_remote.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
diff --git a/xwords4/android/XWords4/res/layout/chat_row.xml b/xwords4/android/XWords4/res/layout/chat_row.xml
new file mode 100644
index 000000000..444e3f4d9
--- /dev/null
+++ b/xwords4/android/XWords4/res/layout/chat_row.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java
index e5a8d0597..40076a28e 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/BoardDelegate.java
@@ -1983,13 +1983,14 @@ public class BoardDelegate extends DelegateBase
// and may stack dialogs on top of this one. Including later
// chat-messages.
@Override
- public void showChat( final String msg, String fromPlayer )
+ public void showChat( final String msg, final int fromIndx,
+ String fromPlayer )
{
if ( BuildConstants.CHAT_SUPPORTED ) {
post( new Runnable() {
public void run() {
- DBUtils.appendChatHistory( m_activity,
- m_rowid, msg, false );
+ DBUtils.appendChatHistory( m_activity, m_rowid, msg,
+ fromIndx );
startChatActivity();
}
} );
@@ -2363,9 +2364,11 @@ public class BoardDelegate extends DelegateBase
private void startChatActivity()
{
if ( BuildConstants.CHAT_SUPPORTED ) {
- Intent intent = new Intent( m_activity, ChatActivity.class );
- intent.putExtra( GameUtils.INTENT_KEY_ROWID, m_rowid );
- startActivityForResult( intent, RequestCode.CHAT_REQUEST );
+ int curPlayer = XwJNI.board_getSelPlayer( m_jniGamePtr );
+ String[] names = m_gi.playerNames();
+ boolean[] locs = m_gi.playersLocal(); // to convert old histories
+ ChatDelegate.startForResult( m_activity, RequestCode.CHAT_REQUEST,
+ m_rowid, curPlayer, names, locs );
}
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java
index 48e8cd607..420090ad8 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/ChatDelegate.java
@@ -30,15 +30,23 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
-import android.widget.LinearLayout;
import android.widget.ScrollView;
+import android.widget.TableLayout;
+import android.widget.TableRow;
import android.widget.TextView;
+import junit.framework.Assert;
+
import org.eehouse.android.xw4.DlgDelegate.Action;
public class ChatDelegate extends DelegateBase {
+ private static final String INTENT_KEY_PLAYER = "intent_key_player";
+ private static final String INTENT_KEY_NAMES = "intent_key_names";
+ private static final String INTENT_KEY_LOCS = "intent_key_locs";
+
private long m_rowid;
+ private int m_curPlayer;
private Activity m_activity;
private EditText mEdit;
@@ -63,20 +71,25 @@ public class ChatDelegate extends DelegateBase {
int before, int count ) {}
} );
- m_rowid = getIntent().getLongExtra( GameUtils.INTENT_KEY_ROWID, -1 );
+ Intent intent = getIntent();
+ m_rowid = intent.getLongExtra( GameUtils.INTENT_KEY_ROWID, -1 );
+ m_curPlayer = intent.getIntExtra( INTENT_KEY_PLAYER, -1 );
+ String[] names = intent.getStringArrayExtra( INTENT_KEY_NAMES );
+ boolean[] locals = intent.getBooleanArrayExtra( INTENT_KEY_LOCS );
- DBUtils.HistoryPair[] pairs = DBUtils.getChatHistory( m_activity, m_rowid );
+ DBUtils.HistoryPair[] pairs
+ = DBUtils.getChatHistory( m_activity, m_rowid, locals );
if ( null != pairs ) {
- LinearLayout layout = (LinearLayout)
+ TableLayout layout = (TableLayout)
findViewById( R.id.chat_history );
for ( DBUtils.HistoryPair pair : pairs ) {
- TextView view = (TextView)
- inflate( pair.sourceLocal
- ? R.layout.chat_history_local
- : R.layout.chat_history_remote );
+ TableRow row = (TableRow)inflate( R.layout.chat_row );
+ TextView view = (TextView)row.findViewById( R.id.chat_row_text );
view.setText( pair.msg );
- layout.addView( view );
+ view = (TextView)row.findViewById( R.id.chat_row_name );
+ view.setText( names[pair.playerIndx] );
+ layout.addView( row );
}
}
@@ -121,7 +134,7 @@ public class ChatDelegate extends DelegateBase {
if ( null == text || text.length() == 0 ) {
setResult( Activity.RESULT_CANCELED );
} else {
- DBUtils.appendChatHistory( m_activity, m_rowid, text, true );
+ DBUtils.appendChatHistory( m_activity, m_rowid, text, m_curPlayer );
Intent result = new Intent();
result.putExtra( BoardDelegate.INTENT_KEY_CHAT, text );
@@ -143,8 +156,8 @@ public class ChatDelegate extends DelegateBase {
case CLEAR_ACTION:
if ( AlertDialog.BUTTON_POSITIVE == which ) {
DBUtils.clearChatHistory( m_activity, m_rowid );
- LinearLayout layout =
- (LinearLayout)findViewById( R.id.chat_history );
+ TableLayout layout =
+ (TableLayout)findViewById( R.id.chat_history );
layout.removeAllViews();
}
break;
@@ -152,4 +165,18 @@ public class ChatDelegate extends DelegateBase {
super.dlgButtonClicked( action, which, params );
}
}
+
+
+ public static void startForResult( Activity parent, RequestCode requestCode,
+ long rowID, int curPlayer,
+ String[] names, boolean[] locs )
+ {
+ Assert.assertFalse( -1 == curPlayer );
+ Intent intent = new Intent( parent, ChatActivity.class );
+ intent.putExtra( GameUtils.INTENT_KEY_ROWID, rowID );
+ intent.putExtra( INTENT_KEY_PLAYER, curPlayer );
+ intent.putExtra( INTENT_KEY_NAMES, names );
+ intent.putExtra( INTENT_KEY_LOCS, locs );
+ parent.startActivityForResult( intent, requestCode.ordinal() );
+ }
}
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 5cc0561e5..d134a784c 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DBUtils.java
@@ -96,13 +96,13 @@ public class DBUtils {
}
public static class HistoryPair {
- private HistoryPair( String p_msg, boolean p_sourceLocal )
+ private HistoryPair( String p_msg, int p_playerIndx )
{
msg = p_msg;
- sourceLocal = p_sourceLocal;
+ playerIndx = p_playerIndx;
}
String msg;
- boolean sourceLocal;
+ int playerIndx;
}
public static class DictBrowseState {
@@ -1176,21 +1176,83 @@ public class DBUtils {
updateRow( context, DBHelper.TABLE_NAME_SUM, rowid, values );
}
- public static HistoryPair[] getChatHistory( Context context, long rowid )
+ private static HistoryPair[] convertChatString( Context context, long rowid,
+ boolean[] playersLocal )
+ {
+ HistoryPair[] result = null;
+ String oldHistory = getChatHistoryStr( context, rowid );
+ if ( null != oldHistory ) {
+ ArrayList valuess = new ArrayList();
+ ArrayList pairs = new ArrayList();
+ String localPrefix = LocUtils.getString( context, R.string.chat_local_id );
+ String rmtPrefix = LocUtils.getString( context, R.string.chat_other_id );
+ String[] msgs = oldHistory.split( "\n" );
+ int localPlayerIndx = -1;
+ int remotePlayerIndx = -1;
+ for ( int ii = playersLocal.length - 1; ii >= 0; --ii ) {
+ if ( playersLocal[ii] ) {
+ localPlayerIndx = ii;
+ } else {
+ remotePlayerIndx = ii;
+ }
+ }
+ for ( String msg : msgs ) {
+ int indx = -1;
+ String prefix = null;
+ if ( msg.startsWith( localPrefix ) ) {
+ prefix = localPrefix;
+ indx = localPlayerIndx;
+ } else if ( msg.startsWith( rmtPrefix ) ) {
+ prefix = rmtPrefix;
+ indx = remotePlayerIndx;
+ }
+ if ( -1 != indx ) {
+ DbgUtils.logf( "removing substring %s; was: %s", prefix, msg );
+ msg = msg.substring( prefix.length(), msg.length() );
+ DbgUtils.logf( "removED substring; now %s", msg );
+ valuess.add( cvForChat( rowid, msg, indx ) );
+
+ HistoryPair pair = new HistoryPair(msg, indx );
+ pairs.add( pair );
+ }
+ }
+ result = pairs.toArray( new HistoryPair[pairs.size()] );
+
+ appendChatHistory( context, valuess );
+ // saveChatHistory( context, rowid, null );
+ }
+ return result;
+ }
+
+ public static HistoryPair[] getChatHistory( Context context, long rowid,
+ boolean[] playersLocal )
{
HistoryPair[] result = null;
if ( BuildConstants.CHAT_SUPPORTED ) {
- final String localPrefix =
- LocUtils.getString( context, R.string.chat_local_id );
- String history = getChatHistoryStr( context, rowid );
- if ( null != history ) {
- String[] msgs = history.split( "\n" );
- result = new HistoryPair[msgs.length];
- for ( int ii = 0; ii < result.length; ++ii ) {
- String msg = msgs[ii];
- boolean isLocal = msg.startsWith( localPrefix );
- result[ii] = new HistoryPair( msg, isLocal );
+ String[] columns = { DBHelper.SENDER, DBHelper.MESSAGE };
+ String selection = String.format( "%s=%d", DBHelper.ROW, rowid );
+ initDB( context );
+ synchronized( s_dbHelper ) {
+ SQLiteDatabase db = s_dbHelper.getReadableDatabase();
+ Cursor cursor = db.query( DBHelper.TABLE_NAME_CHAT, columns,
+ selection, null, null, null, null );
+ if ( 0 < cursor.getCount() ) {
+ result = new HistoryPair[cursor.getCount()];
+ int msgIndex = cursor.getColumnIndex( DBHelper.MESSAGE );
+ int plyrIndex = cursor.getColumnIndex( DBHelper.SENDER );
+ for ( int ii = 0; cursor.moveToNext(); ++ii ) {
+ String msg = cursor.getString( msgIndex );
+ int plyr = cursor.getInt( plyrIndex );
+ HistoryPair pair = new HistoryPair(msg, plyr );
+ result[ii] = pair;
+ }
}
+ cursor.close();
+ db.close();
+ }
+
+ if ( null == result ) {
+ result = convertChatString( context, rowid, playersLocal );
}
}
return result;
@@ -1674,26 +1736,49 @@ public class DBUtils {
return result;
}
- public static void appendChatHistory( Context context, long rowid,
- String msg, boolean local )
+ private static void appendChatHistory( Context context,
+ ArrayList valuess )
{
- if ( BuildConstants.CHAT_SUPPORTED ) {
- Assert.assertNotNull( msg );
- int id = local ? R.string.chat_local_id : R.string.chat_other_id;
- msg = LocUtils.getString( context, id ) + msg;
-
- String cur = getChatHistoryStr( context, rowid );
- if ( null != cur ) {
- msg = cur + "\n" + msg;
+ initDB( context );
+ synchronized( s_dbHelper ) {
+ SQLiteDatabase db = s_dbHelper.getWritableDatabase();
+ for ( ContentValues values : valuess ) {
+ db.insert( DBHelper.TABLE_NAME_CHAT, null, values );
}
-
- saveChatHistory( context, rowid, msg );
+ db.close();
}
+ }
+
+ private static ContentValues cvForChat( long rowid, String msg, int plyr )
+ {
+ ContentValues values = new ContentValues();
+ values.put( DBHelper.ROW, rowid );
+ values.put( DBHelper.MESSAGE, msg );
+ values.put( DBHelper.SENDER, plyr );
+ return values;
+ }
+
+ public static void appendChatHistory( Context context, long rowid,
+ String msg, int fromPlayer )
+ {
+ Assert.assertNotNull( msg );
+ Assert.assertFalse( -1 == fromPlayer );
+ ArrayList valuess = new ArrayList();
+ valuess.add( cvForChat( rowid, msg, fromPlayer ) );
+ appendChatHistory( context, valuess );
+ DbgUtils.logf( "appendChatHistory: inserted %s from player %d",
+ msg, fromPlayer );
} // appendChatHistory
public static void clearChatHistory( Context context, long rowid )
{
- saveChatHistory( context, rowid, null );
+ String selection = String.format( "%s = %d", DBHelper.ROW, rowid );
+ initDB( context );
+ synchronized( s_dbHelper ) {
+ SQLiteDatabase db = s_dbHelper.getWritableDatabase();
+ db.delete( DBHelper.TABLE_NAME_CHAT, selection, null );
+ db.close();
+ }
}
public static void setDBChangeListener( DBChangeListener listener )
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 b189f0675..b5a676eea 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/GameUtils.java
@@ -862,9 +862,9 @@ public class GameUtils {
m_gameOver = false;
}
@Override
- public void showChat( String msg, String fromName )
+ public void showChat( String msg, int fromIndx, String fromName )
{
- DBUtils.appendChatHistory( m_context, m_rowid, msg, false );
+ DBUtils.appendChatHistory( m_context, m_rowid, msg, fromIndx );
m_gotChat = true;
m_chatFrom = fromName;
m_chat = msg;
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
index 8b5b8a20d..d9af90578 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/CurGameInfo.java
@@ -295,6 +295,24 @@ public class CurGameInfo {
return !consistent;
}
+ public String[] playerNames()
+ {
+ String[] names = new String[nPlayers];
+ for ( int ii = 0; ii < nPlayers; ++ii ) {
+ names[ii] = players[ii].name;
+ }
+ return names;
+ }
+
+ public boolean[] playersLocal()
+ {
+ boolean[] locs = new boolean[nPlayers];
+ for ( int ii = 0; ii < nPlayers; ++ii ) {
+ locs[ii] = players[ii].isLocal;
+ }
+ return locs;
+ }
+
public String[] visibleNames( boolean withDicts )
{
String nameFmt = withDicts?
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java
index 48f9a01e6..2ddf76a61 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxt.java
@@ -146,7 +146,7 @@ public interface UtilCtxt {
boolean warnIllegalWord( String dict, String[] words, int turn,
boolean turnLost );
- void showChat( String msg, String fromPlayer );
+ void showChat( String msg, int fromIndx, String fromName );
boolean phoneNumbersSame( String num1, String num2 );
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java
index e0cf3676a..d09e9ef31 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/UtilCtxtImpl.java
@@ -293,7 +293,7 @@ public class UtilCtxtImpl implements UtilCtxt {
}
// These need to go into some sort of chat DB, not dropped.
- public void showChat( String msg, String fromPlayer )
+ public void showChat( String msg, int fromIndx, String fromName )
{
subclassOverride( "showChat" );
}
diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
index 4b2807f26..98cf3a274 100644
--- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
+++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/XwJNI.java
@@ -296,6 +296,7 @@ public class XwJNI {
public static native boolean board_commitTurn( GamePtr gamePtr );
public static native boolean board_flip( GamePtr gamePtr );
public static native boolean board_replaceTiles( GamePtr gamePtr );
+ public static native int board_getSelPlayer( GamePtr gamePtr );
public static native boolean board_redoReplacedTiles( GamePtr gamePtr );
public static native void board_resetEngine( GamePtr gamePtr );
public static native boolean board_requestHint( GamePtr gamePtr,