From b5090bb825d672314b389454ef2d4068aa07f3c0 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 8 Feb 2024 18:56:57 -0800 Subject: [PATCH] add sorting known players by date to android client --- .../android/xw4/KnownPlayersDelegate.java | 23 ++++++++++++++++- .../org/eehouse/android/xw4/jni/XwJNI.java | 12 +++++---- .../app/src/main/res/layout/knownplayrs.xml | 8 +++++- .../app/src/main/res/values/tmpstrings.xml | 2 ++ xwords4/android/jni/xwjni.c | 6 ++--- xwords4/common/knownplyr.c | 25 ++++++++++++++++++- xwords4/common/knownplyr.h | 4 +-- xwords4/linux/gtkinvit.c | 4 +-- xwords4/linux/gtkkpdlg.c | 4 +-- 9 files changed, 71 insertions(+), 17 deletions(-) diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java index d56174a92..23a97af1b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/KnownPlayersDelegate.java @@ -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 mChildren; private HashSet 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 ); diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java index a084d4345..07da5f3e6 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.java @@ -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 ); diff --git a/xwords4/android/app/src/main/res/layout/knownplayrs.xml b/xwords4/android/app/src/main/res/layout/knownplayrs.xml index 650431d68..df860b1b3 100644 --- a/xwords4/android/app/src/main/res/layout/knownplayrs.xml +++ b/xwords4/android/app/src/main/res/layout/knownplayrs.xml @@ -11,7 +11,13 @@ android:layout_height="wrap_content" android:text="@string/knowns_expl" android:textAppearance="?android:attr/textAppearanceMedium" - /> + /> + + Peers information not available Refresh + Sort by date + diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index 368f2d208..9eb79cbcd 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -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(); diff --git a/xwords4/common/knownplyr.c b/xwords4/common/knownplyr.c index 150b3bb8d..2e561c41f 100644 --- a/xwords4/common/knownplyr.c +++ b/xwords4/common/knownplyr.c @@ -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 ); } diff --git a/xwords4/common/knownplyr.h b/xwords4/common/knownplyr.h index b9067623d..387aea3af 100644 --- a/xwords4/common/knownplyr.h +++ b/xwords4/common/knownplyr.h @@ -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, diff --git a/xwords4/linux/gtkinvit.c b/xwords4/linux/gtkinvit.c index adef97ec9..e38142d40 100644 --- a/xwords4/linux/gtkinvit.c +++ b/xwords4/linux/gtkinvit.c @@ -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 ) { diff --git a/xwords4/linux/gtkkpdlg.c b/xwords4/linux/gtkkpdlg.c index af170edcc..5ccf0d93e 100644 --- a/xwords4/linux/gtkkpdlg.c +++ b/xwords4/linux/gtkkpdlg.c @@ -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] );