mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-04 20:46:28 +01:00
add invite history and ability to invite all at once
If inviting known players to a more-than-two-player game, can select all at once. Required using checkboxes instead of radiobuttons for the case where nMissing > 1.
This commit is contained in:
parent
210b0bcbcb
commit
d5be06413f
12 changed files with 231 additions and 58 deletions
|
@ -682,7 +682,8 @@ public class BoardDelegate extends DelegateBase
|
|||
private void showInviteChoicesThen()
|
||||
{
|
||||
NetLaunchInfo nli = nliForMe();
|
||||
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, nli );
|
||||
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, nli,
|
||||
m_mySIS.nMissing );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1111,8 +1112,13 @@ public class BoardDelegate extends DelegateBase
|
|||
break;
|
||||
|
||||
case LAUNCH_INVITE_ACTION:
|
||||
CommsAddrRec addr = (CommsAddrRec)params[0];
|
||||
tryOtherInvites( addr );
|
||||
for ( Object obj : params ) {
|
||||
if ( obj instanceof CommsAddrRec ) {
|
||||
tryOtherInvites( (CommsAddrRec)obj );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ENABLE_NBS_DO:
|
||||
|
@ -1510,6 +1516,23 @@ public class BoardDelegate extends DelegateBase
|
|||
callInviteChoices();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInfoClicked()
|
||||
{
|
||||
SentInvitesInfo sentInfo = DBUtils.getInvitesFor( m_activity, m_rowid );
|
||||
String msg = sentInfo.getAsText( m_activity );
|
||||
makeOkOnlyBuilder( msg )
|
||||
.setTitle( R.string.title_invite_history )
|
||||
.setAction( Action.INVITE_INFO )
|
||||
.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRowID()
|
||||
{
|
||||
return m_rowid;
|
||||
}
|
||||
|
||||
private byte[] getInvite()
|
||||
{
|
||||
byte[] result = null;
|
||||
|
|
|
@ -595,10 +595,10 @@ public abstract class DelegateBase implements DlgClickNotify,
|
|||
m_dlgDelegate.launchLookup( words, lang, !studyOn );
|
||||
}
|
||||
|
||||
protected void showInviteChoicesThen( Action action,
|
||||
NetLaunchInfo nli )
|
||||
protected void showInviteChoicesThen( Action action, NetLaunchInfo nli,
|
||||
int nMissing )
|
||||
{
|
||||
m_dlgDelegate.showInviteChoicesThen( action, nli );
|
||||
m_dlgDelegate.showInviteChoicesThen( action, nli, nMissing );
|
||||
}
|
||||
|
||||
public Builder makeOkOnlyBuilder( int msgID )
|
||||
|
|
|
@ -401,11 +401,11 @@ public class DlgDelegate {
|
|||
}
|
||||
|
||||
public void showInviteChoicesThen( final Action action,
|
||||
NetLaunchInfo nli )
|
||||
NetLaunchInfo nli, int nMissing )
|
||||
{
|
||||
DlgState state = new DlgState( DlgID.INVITE_CHOICES_THEN )
|
||||
.setAction( action )
|
||||
.setParams( nli );
|
||||
.setParams( nli, nMissing );
|
||||
m_dlgt.show( state );
|
||||
}
|
||||
|
||||
|
|
|
@ -84,10 +84,14 @@ public class InviteChoicesAlert extends DlgDelegateAlert
|
|||
InviteMeans lastMeans = null;
|
||||
NetLaunchInfo nli = null;
|
||||
Object[] params = state.getParams();
|
||||
int nMissing = 0;
|
||||
if ( null != params ) {
|
||||
if ( 0 < params.length && params[0] instanceof NetLaunchInfo ) {
|
||||
nli = (NetLaunchInfo)params[0];
|
||||
}
|
||||
if ( 1 < params.length && params[1] instanceof Integer ) {
|
||||
nMissing = (Integer)params[1];
|
||||
}
|
||||
}
|
||||
means.add( InviteMeans.EMAIL );
|
||||
means.add( InviteMeans.SMS_USER );
|
||||
|
@ -130,11 +134,15 @@ public class InviteChoicesAlert extends DlgDelegateAlert
|
|||
InviteMeans means = (InviteMeans)choice;
|
||||
activity.inviteChoiceMade( state.m_action,
|
||||
means, state.getParams() );
|
||||
} else if ( choice instanceof String ) {
|
||||
String player = (String)choice;
|
||||
} else if ( choice instanceof String[] ) {
|
||||
String[] players = (String[])choice;
|
||||
Object[] params = new Object[players.length];
|
||||
for ( int ii = 0; ii < params.length; ++ii ) {
|
||||
String player = players[ii];
|
||||
CommsAddrRec addr = XwJNI.kplr_getAddr( player );
|
||||
params[ii] = addr;
|
||||
}
|
||||
XWActivity xwact = (XWActivity)context;
|
||||
Object[] params = { addr };
|
||||
xwact.onPosButton( state.m_action, params );
|
||||
} else {
|
||||
Assert.failDbg();
|
||||
|
@ -151,7 +159,7 @@ public class InviteChoicesAlert extends DlgDelegateAlert
|
|||
;
|
||||
|
||||
String[] players = XwJNI.kplr_getPlayers();
|
||||
mInviteView.setChoices( means, lastSelMeans, players )
|
||||
mInviteView.setChoices( means, lastSelMeans, players, nMissing )
|
||||
.setNli( nli )
|
||||
.setCallbacks( this )
|
||||
;
|
||||
|
|
|
@ -59,10 +59,9 @@ public class InviteView extends ScrollView
|
|||
private ItemClicked mProcs;
|
||||
private boolean mIsWho;
|
||||
private RadioGroup mGroupTab;
|
||||
private RadioGroup mGroupWho;
|
||||
private LimSelGroup mGroupWho;
|
||||
private RadioGroup mGroupHow;
|
||||
private Map<RadioButton, InviteMeans> mHowMeans = new HashMap<>();
|
||||
private Map<RadioButton, String> mWhoPlayers = new HashMap<>();
|
||||
private boolean mExpanded = false;
|
||||
private NetLaunchInfo mNli;
|
||||
|
||||
|
@ -71,7 +70,7 @@ public class InviteView extends ScrollView
|
|||
}
|
||||
|
||||
public InviteView setChoices( List<InviteMeans> meansList, int sel,
|
||||
String[] players )
|
||||
String[] players, int maxPlayers )
|
||||
{
|
||||
final Context context = getContext();
|
||||
|
||||
|
@ -104,15 +103,10 @@ public class InviteView extends ScrollView
|
|||
}
|
||||
|
||||
if ( haveWho ) {
|
||||
mGroupWho = (RadioGroup)findViewById( R.id.group_who );
|
||||
mGroupWho.setOnCheckedChangeListener( this );
|
||||
for ( String player : players ) {
|
||||
RadioButton button = (RadioButton)LocUtils
|
||||
.inflate( context, R.layout.invite_radio );
|
||||
button.setText( player );
|
||||
mGroupWho.addView( button );
|
||||
mWhoPlayers.put( button, player );
|
||||
}
|
||||
mGroupWho = ((LimSelGroup)findViewById( R.id.group_who ))
|
||||
.setLimit( maxPlayers )
|
||||
.addPlayers( players )
|
||||
;
|
||||
}
|
||||
mIsWho = false; // start with how
|
||||
showWhoOrHow();
|
||||
|
@ -139,20 +133,22 @@ public class InviteView extends ScrollView
|
|||
return this;
|
||||
}
|
||||
|
||||
public InviteView setCallbacks( ItemClicked procs ) {
|
||||
public InviteView setCallbacks( ItemClicked procs )
|
||||
{
|
||||
mProcs = procs;
|
||||
mGroupWho.setCallbacks( procs );
|
||||
return this;
|
||||
}
|
||||
|
||||
public Object getChoice()
|
||||
{
|
||||
Object result = null;
|
||||
RadioButton checked = getCurCheckedFor();
|
||||
if ( null != checked ) {
|
||||
if ( mIsWho ) {
|
||||
result = mWhoPlayers.get(checked);
|
||||
result = mGroupWho.getSelected();
|
||||
} else {
|
||||
result = mHowMeans.get(checked);
|
||||
int curSel = mGroupHow.getCheckedRadioButtonId();
|
||||
if ( 0 <= curSel ) {
|
||||
result = (RadioButton)findViewById(curSel);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -187,17 +183,6 @@ public class InviteView extends ScrollView
|
|||
.setVisibility( show ? View.VISIBLE: View.GONE );
|
||||
}
|
||||
|
||||
private RadioButton getCurCheckedFor()
|
||||
{
|
||||
RadioButton result = null;
|
||||
RadioGroup group = mIsWho ? mGroupWho : mGroupHow;
|
||||
int curSel = group.getCheckedRadioButtonId();
|
||||
if ( 0 <= curSel ) {
|
||||
result = (RadioButton)findViewById(curSel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void showWhoOrHow()
|
||||
{
|
||||
if ( null != mGroupWho ) {
|
||||
|
@ -205,7 +190,7 @@ public class InviteView extends ScrollView
|
|||
}
|
||||
mGroupHow.setVisibility( mIsWho ? View.INVISIBLE : View.VISIBLE );
|
||||
|
||||
boolean showEmpty = mIsWho && 0 == mWhoPlayers.size();
|
||||
boolean showEmpty = mIsWho && 0 == mGroupWho.getChildCount();
|
||||
findViewById( R.id.who_empty )
|
||||
.setVisibility( showEmpty ? View.VISIBLE : View.INVISIBLE );
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.content.DialogInterface;
|
|||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.eehouse.android.xw4.DBUtils.SentInvitesInfo;
|
||||
import org.eehouse.android.xw4.DlgDelegate.Action;
|
||||
import org.eehouse.android.xw4.Perms23.Perm;
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
|
@ -57,12 +58,14 @@ class InvitesNeededAlert {
|
|||
|
||||
interface Callbacks {
|
||||
DelegateBase getDelegate();
|
||||
long getRowID();
|
||||
void onCloseClicked();
|
||||
void onInviteClicked();
|
||||
void onInfoClicked();
|
||||
}
|
||||
|
||||
static void showOrHide( Callbacks callbacks, int nDevsSeen, int nPlayersMissing,
|
||||
boolean isRematch )
|
||||
static void showOrHide( Callbacks callbacks, int nDevsSeen,
|
||||
int nPlayersMissing, boolean isRematch )
|
||||
{
|
||||
DbgUtils.assertOnUIThread();
|
||||
InvitesNeededAlert self = sInstance[0];
|
||||
|
@ -102,8 +105,8 @@ class InvitesNeededAlert {
|
|||
}
|
||||
}
|
||||
|
||||
private static void makeNew( Callbacks callbacks,
|
||||
int nDevsSeen, int nPlayersMissing, boolean isRematch )
|
||||
private static void makeNew( Callbacks callbacks, int nDevsSeen,
|
||||
int nPlayersMissing, boolean isRematch )
|
||||
{
|
||||
Log.d( TAG, "makeNew(nDevsSeen=%d, nPlayersMissing=%d)", nDevsSeen, nPlayersMissing );
|
||||
State state = new State( nDevsSeen, nPlayersMissing, isRematch );
|
||||
|
@ -174,6 +177,22 @@ class InvitesNeededAlert {
|
|||
}
|
||||
} );
|
||||
|
||||
if ( BuildConfig.NON_RELEASE ) {
|
||||
long rowid = mCallbacks.getRowID();
|
||||
SentInvitesInfo sentInfo = DBUtils.getInvitesFor( context, rowid );
|
||||
int nSent = sentInfo.getMinPlayerCount();
|
||||
boolean invitesSent = nSent >= state.nPlayersMissing;
|
||||
if ( invitesSent ) {
|
||||
alert.setNoDismissListenerNeut( ab, R.string.newgame_invite_more,
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
public void onClick( DialogInterface dlg, int item ) {
|
||||
onNeutClick();
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
alert.setNoDismissListenerNeg( ab, R.string.button_close,
|
||||
new OnClickListener() {
|
||||
@Override
|
||||
|
@ -191,6 +210,11 @@ class InvitesNeededAlert {
|
|||
mCallbacks.onInviteClicked();
|
||||
}
|
||||
|
||||
private void onNeutClick()
|
||||
{
|
||||
mCallbacks.onInfoClicked();
|
||||
}
|
||||
|
||||
private void onNegClick()
|
||||
{
|
||||
Log.d( TAG, "onNegClick()" );
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
/* -*- 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.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eehouse.android.xw4.loc.LocUtils;
|
||||
|
||||
public class LimSelGroup extends LinearLayout
|
||||
implements OnCheckedChangeListener {
|
||||
private static final String TAG = LimSelGroup.class.getSimpleName();
|
||||
|
||||
private int mLimit;
|
||||
private InviteView.ItemClicked mProcs;
|
||||
|
||||
public LimSelGroup( Context context, AttributeSet as )
|
||||
{
|
||||
super( context, as );
|
||||
}
|
||||
|
||||
LimSelGroup setLimit( int limit )
|
||||
{
|
||||
Assert.assertTrueNR( 0 < limit );
|
||||
mLimit = limit;
|
||||
return this;
|
||||
}
|
||||
|
||||
void setCallbacks( InviteView.ItemClicked procs )
|
||||
{
|
||||
mProcs = procs;
|
||||
}
|
||||
|
||||
String[] getSelected()
|
||||
{
|
||||
String[] result = null;
|
||||
int len = mChecked.size();
|
||||
if ( 0 < len ) {
|
||||
result = new String[mChecked.size()];
|
||||
for ( int ii = 0; ii < result.length; ++ii ) {
|
||||
result[ii] = mChecked.get(ii).getText().toString();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LimSelGroup addPlayers( String[] names )
|
||||
{
|
||||
Context context = getContext();
|
||||
for ( String name : names ) {
|
||||
CompoundButton button;
|
||||
if ( 1 == mLimit ) {
|
||||
button = (RadioButton)LocUtils.inflate( context, R.layout.invite_radio );
|
||||
} else {
|
||||
button = (CheckBox)LocUtils.inflate( context, R.layout.invite_checkbox );
|
||||
}
|
||||
button.setText( name );
|
||||
button.setOnCheckedChangeListener( this );
|
||||
addView( button );
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged( CompoundButton buttonView, boolean isChecked )
|
||||
{
|
||||
Log.d( TAG, "onCheckedChanged(%s, %b)", buttonView, isChecked );
|
||||
addToSet( buttonView, isChecked );
|
||||
if ( null != mProcs ) {
|
||||
mProcs.checkButton();
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<CompoundButton> mChecked = new ArrayList<>();
|
||||
private void addToSet( CompoundButton button, boolean nowChecked )
|
||||
{
|
||||
for ( Iterator<CompoundButton> iter = mChecked.iterator();
|
||||
iter.hasNext(); ) {
|
||||
CompoundButton but = iter.next();
|
||||
if ( nowChecked ) {
|
||||
Assert.assertTrueNR( ! but.equals(button) );
|
||||
} else if ( but.equals(button) ) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
if ( nowChecked ) {
|
||||
mChecked.add( button );
|
||||
while ( mLimit < mChecked.size() ) {
|
||||
CompoundButton oldButton = mChecked.remove( 0 );
|
||||
oldButton.setChecked( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/invite_who_elem"
|
||||
/>
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RadioButton xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textSize="22dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
style="@style/invite_who_elem"
|
||||
/>
|
||||
|
|
|
@ -44,9 +44,11 @@
|
|||
<FrameLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
<RadioGroup android:id="@+id/group_who"
|
||||
<org.eehouse.android.xw4.LimSelGroup
|
||||
android:id="@+id/group_who"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
/>
|
||||
|
||||
<RadioGroup android:id="@+id/group_how"
|
||||
|
|
|
@ -1025,7 +1025,8 @@
|
|||
<string name="newgame_invite">Invite now</string>
|
||||
<!-- Button offering to invite Known Player to a new game -->
|
||||
<string name="invite_player_fmt">Invite %1$s</string>
|
||||
<string name="newgame_invite_more">More info</string>
|
||||
<string name="newgame_invite_more">History</string>
|
||||
<string name="title_invite_history">Invitations Sent</string>
|
||||
<string name="newgame_drop_relay">Drop Relay</string>
|
||||
|
||||
<!-- EXPLAIN ME -->
|
||||
|
|
|
@ -166,4 +166,12 @@
|
|||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:drawSelectorOnTop">true</item>
|
||||
</style>
|
||||
|
||||
<style name="invite_who_elem">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:textSize">22dp</item>
|
||||
<item name="android:paddingTop">5dp</item>
|
||||
<item name="android:paddingBottom">5dp</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
Loading…
Add table
Reference in a new issue