add known players browser

There's lots to do, but it shows what's know about each one and has
unimplemented UI for changing names and deleting.
This commit is contained in:
Eric House 2020-09-26 19:22:03 -07:00
parent 9b12f60dbf
commit 9bc73b8bfc
14 changed files with 389 additions and 6 deletions

View file

@ -134,8 +134,8 @@
android:windowSoftInputMode="stateAlwaysHidden|adjustPan"
/>
<activity android:name="StudyListActivity"
/>
<activity android:name="StudyListActivity" />
<activity android:name="KnownPlayersActivity" />
<receiver android:name="OnBootReceiver">
<intent-filter>

View file

@ -113,6 +113,9 @@ public class DlgDelegate {
// DwnldDelegate && GamesListDelegate
STORAGE_CONFIRMED,
// Known Players
KNOWN_PLAYER_DELETE,
// classify me
ENABLE_NBS_ASK,
ENABLE_NBS_DO,

View file

@ -70,6 +70,7 @@ public enum DlgID {
, ASK_DUP_PAUSE
, CHOOSE_TILES
, SHOW_TILES
, RENAME_PLAYER
;
private boolean m_addToStack;

View file

@ -1715,6 +1715,9 @@ public class GamesListDelegate extends ListDelegateBase
enable = nothingSelected && XWPrefs.getStudyEnabled( m_activity );
Utils.setItemVisible( menu, R.id.games_menu_study, enable );
enable = BuildConfig.HAVE_KNOWN_PLAYERS && nothingSelected;
Utils.setItemVisible( menu, R.id.games_menu_knownplyrs, enable );
enable = nothingSelected &&
0 < DBUtils.getGamesWithSendsPending( m_activity ).size();
Utils.setItemVisible( menu, R.id.games_menu_resend, enable );
@ -1806,6 +1809,10 @@ public class GamesListDelegate extends ListDelegateBase
StudyListDelegate.launchOrAlert( getDelegator(), StudyListDelegate.NO_LANG, this );
break;
case R.id.games_menu_knownplyrs:
KnownPlayersDelegate.launchOrAlert( getDelegator(), this );
break;
case R.id.games_menu_about:
show( AboutAlert.newInstance() );
break;

View file

@ -0,0 +1,33 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.os.Bundle;
public class KnownPlayersActivity extends XWActivity {
@Override
protected void onCreate( Bundle savedInstanceState )
{
KnownPlayersDelegate dlgt =
new KnownPlayersDelegate( this, savedInstanceState );
super.onCreate( savedInstanceState, dlgt );
}
}

View file

@ -0,0 +1,189 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2020 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.ClipboardManager;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.ListView;
import org.eehouse.android.xw4.DlgDelegate.Action;
import org.eehouse.android.xw4.ExpandImageButton.ExpandChangeListener;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.jni.CommsAddrRec;
import org.eehouse.android.xw4.jni.GameSummary;
import org.eehouse.android.xw4.jni.XwJNI;
import org.eehouse.android.xw4.loc.LocUtils;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class KnownPlayersDelegate extends DelegateBase {
private static final String TAG = KnownPlayersDelegate.class.getSimpleName();
private Activity mActivity;
private ViewGroup mList;
protected KnownPlayersDelegate( Delegator delegator, Bundle sis )
{
super( delegator, sis, R.layout.knownplayrs );
mActivity = delegator.getActivity();
}
@Override
protected void init( Bundle sis )
{
mList = (ViewGroup)findViewById( R.id.players_list );
String[] players = XwJNI.kplr_getPlayers();
for ( String player : players ) {
View child = makePlayerElem( player );
if ( null != child ) {
mList.addView( child );
}
}
}
@Override
public boolean onPosButton( Action action, Object[] params )
{
boolean handled = true;
switch ( action ) {
case KNOWN_PLAYER_DELETE:
Utils.notImpl( mActivity );
break;
default:
handled = super.onPosButton( action, params );
break;
}
return handled;
}
private View makePlayerElem( final String player )
{
View view = null;
CommsAddrRec addr = XwJNI.kplr_getAddr( player );
if ( null != addr ) {
final ViewGroup item = (ViewGroup)LocUtils.inflate( mActivity, R.layout.knownplayrs_item );
TextView tv = (TextView)item.findViewById( R.id.player_name );
tv.setText( player );
view = item;
// Iterate over address types
CommsConnTypeSet conTypes = addr.conTypes;
ViewGroup list = (ViewGroup)item.findViewById( R.id.items );
if ( BuildConfig.NON_RELEASE ) {
if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_MQTT ) ) {
addListing( list, R.string.knowns_mqtt_fmt, addr.mqtt_devID );
}
// if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_RELAY ) ) {
// addListing( item, R.string.knowns_relay_fmt, addr.relay_devID );
// }
}
if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_BT ) ) {
addListing( list, R.string.knowns_bt_fmt, addr.bt_hostName );
}
if ( conTypes.contains( CommsAddrRec.CommsConnType.COMMS_CONN_SMS ) ) {
addListing( list, R.string.knowns_smsphone_fmt, addr.sms_phone );
}
item.findViewById( R.id.player_edit_name )
.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View view ) {
Utils.notImpl( mActivity );
}
} );
item.findViewById( R.id.player_delete )
.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick( View view ) {
confirmAndDelete( player );
}
} );
ExpandImageButton eib = (ExpandImageButton)item.findViewById( R.id.expander );
eib.setOnExpandChangedListener( new ExpandChangeListener() {
@Override
public void expandedChanged( boolean nowExpanded )
{
item.findViewById(R.id.hidden_part)
.setVisibility(nowExpanded?View.VISIBLE:View.GONE);
}
} );
}
return view;
}
private void addListing( ViewGroup parent, int fmtID, String elem )
{
String content = LocUtils.getString( mActivity, fmtID, elem );
TextView item = (TextView)LocUtils.inflate( mActivity, R.layout.knownplayrs_item_line );
item.setText( content );
parent.addView( item );
}
private void editName( String name )
{
Log.d( TAG, "editName(%s) not implemented yet", name );
}
private void confirmAndDelete( String name )
{
String msg = LocUtils.getString( mActivity,
R.string.player_delete_confirm_fmt,
name );
makeConfirmThenBuilder( msg, Action.KNOWN_PLAYER_DELETE )
.show();
}
public static void launchOrAlert( Delegator delegator,
DlgDelegate.HasDlgDelegate dlg )
{
Activity activity = delegator.getActivity();
if ( XwJNI.hasKnownPlayers() ) {
if ( delegator.inDPMode() ) {
delegator.addFragment( KnownPlayersFrag.newInstance( delegator ),
null );
} else {
Intent intent = new Intent( activity, KnownPlayersActivity.class );
activity.startActivity( intent );
}
} else {
dlg.makeOkOnlyBuilder( R.string.no_knowns_expl )
.show();
}
}
}

View file

@ -0,0 +1,39 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2014 - 2020 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.eehouse.android.xw4;
import android.os.Bundle;
public class KnownPlayersFrag extends XWFragment {
public KnownPlayersFrag() {}
public static XWFragment newInstance( Delegator parent )
{
return new KnownPlayersFrag().setParentName( parent );
}
@Override
public void onCreate( Bundle sis )
{
super.onCreate( new KnownPlayersDelegate( this, sis ), sis, true );
}
}

View file

@ -65,7 +65,6 @@ public class StudyListDelegate extends ListDelegateBase
private Set<String> m_checkeds;
private int m_langPosition;
private SLWordsAdapter m_adapter;
private ListView m_list;
private String m_origTitle;
protected StudyListDelegate( Delegator delegator, Bundle sis )
@ -77,8 +76,6 @@ public class StudyListDelegate extends ListDelegateBase
@Override
protected void init( Bundle sis )
{
m_list = (ListView)findViewById( android.R.id.list );
m_pickView = (LabeledSpinner)findViewById( R.id.pick_lang );
m_spinner = m_pickView.getSpinner();
m_checkeds = new HashSet<>();

View file

@ -39,7 +39,6 @@ import android.widget.ListView;
import org.eehouse.android.xw4.DlgDelegate.Action;
public class XWActivity extends FragmentActivity
implements Delegator, DlgDelegate.DlgClickNotify {
private static final String TAG = XWActivity.class.getSimpleName();
@ -257,11 +256,13 @@ public class XWActivity extends FragmentActivity
return false;
}
@Override
public void addFragment( XWFragment fragment, Bundle extras )
{
Assert.failDbg();
}
@Override
public void addFragmentForResult( XWFragment fragment, Bundle extras,
RequestCode request )
{

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<ScrollView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:paddingLeft="8dp"
android:paddingRight="8dp"
>
<!-- Players go here. -->
<LinearLayout android:id="@+id/players_list"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:drawSelectorOnTop="false"
/>
</ScrollView>
</LinearLayout>

View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView android:id="@+id/player_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_weight="1"
/>
<org.eehouse.android.xw4.ExpandImageButton
android:id="@+id/expander"
style="@style/expander_button"
/>
</LinearLayout>
<LinearLayout android:id="@+id/hidden_part"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
>
<!-- Fields will be added here... -->
<LinearLayout android:id="@+id/items"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
/>
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<Button android:id="@+id/player_edit_name"
android:text="@string/player_edit_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<Button android:id="@+id/player_delete"
android:text="@string/button_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>

View file

@ -36,6 +36,9 @@
<item android:id="@+id/games_menu_study"
android:title="@string/gamel_menu_study"
/>
<item android:id="@+id/games_menu_knownplyrs"
android:title="@string/gamel_menu_knownplyrs"
/>
<item android:id="@+id/games_menu_email"
android:title="@string/board_menu_file_email"
android:icon="@drawable/email__gen"

View file

@ -2644,4 +2644,25 @@
<string name="mqtt_invite_title">MQTT Invitation</string>
<string name="not_again_comms_mqtt">Im experimenting with this
as a replacement for the relay.</string>
<!-- Title of menuitem that launches Known Players viewer -->
<string name="gamel_menu_knownplyrs">Known Players…</string>
<!-- Shown instead of Known Players viewer when there aren't any -->
<string name="no_knowns_expl">There havent been any Known Players
saved yet. Known Players are harvested from networked games after
they connect successfully. Give it time.</string>
<string name="knowns_mqtt_fmt">MQTT DevID: %1$s</string>
<string name="knowns_bt_fmt">Bluetooth name: %1$s</string>
<string name="knowns_smsphone_fmt">SMS Phone: %1$s</string>
<!-- Button in known player list element allowing to edit player's name -->
<string name="player_edit_name">Change name</string>
<!-- Shown to confirm deletion of a Knows Players viewer list item -->
<string name="player_delete_confirm_fmt">Are you sure you want to
delete the Known Player “%1$s”?\n\n(This action cannot be
undone.)</string>
</resources>