add sorting known players by date to android client

This commit is contained in:
Eric House 2024-02-08 18:56:57 -08:00
parent 183b656d2a
commit b5090bb825
9 changed files with 71 additions and 17 deletions

View file

@ -29,7 +29,10 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import java.text.DateFormat;
import java.util.ArrayList;
@ -53,11 +56,13 @@ import org.eehouse.android.xw4.loc.LocUtils;
public class KnownPlayersDelegate extends DelegateBase {
private static final String TAG = KnownPlayersDelegate.class.getSimpleName();
private static final String KEY_EXPSET = TAG + "/expset";
private static final String KEY_BY_DATE = TAG + "/bydate";
private Activity mActivity;
private ViewGroup mList;
private List<ViewGroup> mChildren;
private HashSet<String> mExpSet;
private boolean mByDate;
protected KnownPlayersDelegate( Delegator delegator, Bundle sis )
{
@ -69,7 +74,22 @@ public class KnownPlayersDelegate extends DelegateBase {
protected void init( Bundle sis )
{
mList = (ViewGroup)findViewById( R.id.players_list );
loadExpanded();
mByDate = DBUtils.getBoolFor( mActivity, KEY_BY_DATE, false );
CheckBox sortCheck = (CheckBox)findViewById( R.id.sort_box );
sortCheck.setOnCheckedChangeListener( new OnCheckedChangeListener() {
@Override
public void onCheckedChanged( CompoundButton buttonView,
boolean checked ) {
DBUtils.setBoolFor( mActivity, KEY_BY_DATE, checked );
mByDate = checked;
populateList();
}
} );
sortCheck.setChecked( mByDate );
populateList();
}
@ -135,12 +155,13 @@ public class KnownPlayersDelegate extends DelegateBase {
private void populateList()
{
String[] players = XwJNI.kplr_getPlayers();
String[] players = XwJNI.kplr_getPlayers( mByDate );
if ( null == players ) {
finish();
} else {
mChildren = new ArrayList<>();
for ( String player : players ) {
Log.d( TAG, "populateList(): player: %s", player );
ViewGroup child = makePlayerElem( player );
if ( null != child ) {
mChildren.add( child );

View file

@ -190,13 +190,15 @@ public class XwJNI {
}
public static String[] kplr_getPlayers()
{
return kplr_getPlayers( false );
}
public static String[] kplr_getPlayers( boolean byDate )
{
String[] result = null;
if ( BuildConfig.HAVE_KNOWN_PLAYERS ) {
result = kplr_getPlayers( getJNI().m_ptrGlobals );
if ( null != result ) {
Arrays.sort( result );
}
result = kplr_getPlayers( getJNI().m_ptrGlobals, byDate );
}
return result;
}
@ -791,7 +793,7 @@ public class XwJNI {
dvc_makeMQTTNoSuchGames( long jniState, String addressee, int gameID );
private static native void dvc_parseMQTTPacket( long jniState, String topic,
byte[] buf );
private static native String[] kplr_getPlayers( long jniState );
private static native String[] kplr_getPlayers( long jniState, boolean byDate );
private static native boolean kplr_renamePlayer( long jniState, String oldName,
String newName );
private static native void kplr_deletePlayer( long jniState, String player );

View file

@ -13,6 +13,12 @@
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<CheckBox android:id="@+id/sort_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/sort_by_date_label"
/>
<ScrollView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"

View file

@ -9,4 +9,6 @@
<string name="no_peers_info">Peers information not available</string>
<string name="button_refresh">Refresh</string>
<string name="sort_by_date_label">Sort by date</string>
</resources>

View file

@ -771,16 +771,16 @@ Java_org_eehouse_android_xw4_jni_XwJNI_dvc_1parseMQTTPacket
# ifdef XWFEATURE_KNOWNPLAYERS
JNIEXPORT jobjectArray JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_kplr_1getPlayers
( JNIEnv* env, jclass C, jlong jniGlobalPtr )
( JNIEnv* env, jclass C, jlong jniGlobalPtr, jboolean byDate )
{
jobjectArray jnames = NULL;
DVC_HEADER(jniGlobalPtr);
XP_U16 nFound = 0;
kplr_getNames( globalState->dutil, env, NULL, &nFound );
kplr_getNames( globalState->dutil, env, byDate, NULL, &nFound );
if ( 0 < nFound ) {
const XP_UCHAR* names[nFound];
kplr_getNames( globalState->dutil, env, names, &nFound );
kplr_getNames( globalState->dutil, env, byDate, names, &nFound );
jnames = makeStringArray( env, nFound, names );
}
DVC_HEADER_END();

View file

@ -173,6 +173,20 @@ compByName(const DLHead* dl1, const DLHead* dl2)
return XP_STRCMP( kp1->name, kp2->name );
}
static int
compByDate(const DLHead* dl1, const DLHead* dl2)
{
const KnownPlayer* kp1 = (const KnownPlayer*)dl1;
const KnownPlayer* kp2 = (const KnownPlayer*)dl2;
int result = 0;
if ( kp1->newestMod < kp2->newestMod ) {
result = 1;
} else if ( kp1->newestMod > kp2->newestMod ) {
result = -1;
}
return result;
}
/* Adding players is the hard part. There will be a lot with the same name and
* representing the same device. That's easy: skip adding a new entry, but if
* there's a change or addition, make it. For changes, e.g. a different
@ -242,6 +256,7 @@ kplr_addAddrs( XW_DUtilCtxt* dutil, XWEnv xwe, const CurGameInfo* gi,
CommsAddrRec addrs[], XP_U16 nAddrs, XP_U32 modTime )
{
XP_LOGFF( "(nAddrs=%d)", nAddrs );
XP_ASSERT( modTime );
XP_Bool canUse = XP_TRUE;
for ( int ii = 0; ii < nAddrs && canUse; ++ii ) {
canUse = addr_hasType( &addrs[ii], COMMS_CONN_MQTT );
@ -305,11 +320,19 @@ getPlayersImpl( const KPState* state, const XP_UCHAR** players,
}
void
kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe,
kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, XP_Bool byDate,
const XP_UCHAR** players, XP_U16* nFound )
{
KPState* state = loadState( dutil, xwe );
if ( byDate ) {
state->players = (KnownPlayer*)dll_sort( &state->players->links,
compByDate );
}
getPlayersImpl( state, players, nFound );
if ( byDate ) {
state->players = (KnownPlayer*)dll_sort( &state->players->links,
compByName );
}
releaseState( dutil, xwe, state );
}

View file

@ -39,8 +39,8 @@ void kplr_cleanup( XW_DUtilCtxt* dutil );
XP_Bool kplr_havePlayers( XW_DUtilCtxt* dutil, XWEnv xwe );
void kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR** players,
XP_U16* nFound );
void kplr_getNames( XW_DUtilCtxt* dutil, XWEnv xwe, XP_Bool byDate,
const XP_UCHAR** players, XP_U16* nFound );
XP_Bool kplr_getAddr( XW_DUtilCtxt* dutil, XWEnv xwe, const XP_UCHAR* name,
CommsAddrRec* addr, XP_U32* lastMod );
const XP_UCHAR* kplr_nameForMqttDev( XW_DUtilCtxt* dutil, XWEnv xwe,

View file

@ -293,10 +293,10 @@ makeKnownsPage( GtkInviteState* state, PageData* data )
gtk_box_pack_start( GTK_BOX(hbox), label, FALSE, TRUE, 0 );
XP_U16 nFound = 0;
kplr_getNames( state->dutil, NULL_XWE, NULL, &nFound );
kplr_getNames( state->dutil, NULL_XWE, XP_FALSE, NULL, &nFound );
XP_ASSERT( nFound > 0 );
const XP_UCHAR* names[nFound];
kplr_getNames( state->dutil, NULL_XWE, names, &nFound );
kplr_getNames( state->dutil, NULL_XWE, XP_FALSE, names, &nFound );
GtkWidget* combo = state->knownsCombo = gtk_combo_box_text_new();
for ( int ii = 0; ii < nFound; ++ii ) {

View file

@ -147,9 +147,9 @@ gtkkp_show( GtkAppGlobals* apg, GtkWindow* parent )
XW_DUtilCtxt* dutil = apg->cag.params->dutil;
XP_U16 nFound = 0;
kplr_getNames( dutil, NULL_XWE, NULL, &nFound );
kplr_getNames( dutil, NULL_XWE, XP_FALSE, NULL, &nFound );
const XP_UCHAR* players[nFound];
kplr_getNames( dutil, NULL_XWE, players, &nFound );
kplr_getNames( dutil, NULL_XWE, XP_FALSE, players, &nFound );
for ( int ii = 0; ii < nFound; ++ii ) {
XP_LOGFF( "got one: %s", players[ii] );