add qrcode for invite to invite-how alert

Need to find the right place for it, explain it, and get rid of the
alert it's part of when the invite is accepted.
This commit is contained in:
Eric House 2020-10-04 21:18:07 -07:00
parent 6ae1ec9f81
commit 359e1d12d1
9 changed files with 93 additions and 14 deletions

View file

@ -333,6 +333,8 @@ dependencies {
implementation 'com.github.eehouse:nbsproxy:v0.2.2' implementation 'com.github.eehouse:nbsproxy:v0.2.2'
implementation "org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.+" implementation "org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.+"
implementation 'com.google.zxing:core:3.3.+'
} }
task mkImages(type: Exec) { task mkImages(type: Exec) {

View file

@ -821,7 +821,8 @@ public class BoardDelegate extends DelegateBase
private void showInviteChoicesThen( Object[] params ) private void showInviteChoicesThen( Object[] params )
{ {
SentInvitesInfo info = (SentInvitesInfo)params[0]; SentInvitesInfo info = (SentInvitesInfo)params[0];
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, info ); NetLaunchInfo nli = nliForMe();
showInviteChoicesThen( Action.LAUNCH_INVITE_ACTION, info, nli );
} }
@Override @Override

View file

@ -595,9 +595,10 @@ public class DelegateBase implements DlgClickNotify,
} }
protected void showInviteChoicesThen( Action action, protected void showInviteChoicesThen( Action action,
DBUtils.SentInvitesInfo info ) DBUtils.SentInvitesInfo info,
NetLaunchInfo nli)
{ {
m_dlgDelegate.showInviteChoicesThen( action, info ); m_dlgDelegate.showInviteChoicesThen( action, info, nli );
} }
public Builder makeOkOnlyBuilder( int msgID ) public Builder makeOkOnlyBuilder( int msgID )

View file

@ -394,11 +394,12 @@ public class DlgDelegate {
} }
public void showInviteChoicesThen( final Action action, public void showInviteChoicesThen( final Action action,
SentInvitesInfo info ) SentInvitesInfo info,
NetLaunchInfo nli )
{ {
DlgState state = new DlgState( DlgID.INVITE_CHOICES_THEN ) DlgState state = new DlgState( DlgID.INVITE_CHOICES_THEN )
.setAction( action ) .setAction( action )
.setParams( info ); .setParams( info, nli );
m_dlgt.show( state ); m_dlgt.show( state );
} }

View file

@ -55,12 +55,16 @@ public class InviteChoicesAlert extends DlgDelegateAlert
{ {
ArrayList<InviteMeans> means = new ArrayList<>(); ArrayList<InviteMeans> means = new ArrayList<>();
InviteMeans lastMeans = null; InviteMeans lastMeans = null;
NetLaunchInfo nli = null;
Object[] params = state.getParams(); Object[] params = state.getParams();
if ( null != params if ( null != params ) {
&& params[0] instanceof SentInvitesInfo ) { if ( 0 < params.length && params[0] instanceof SentInvitesInfo ) {
lastMeans = ((SentInvitesInfo)params[0]).getLastMeans(); lastMeans = ((SentInvitesInfo)params[0]).getLastMeans();
}
if ( 1 < params.length && params[1] instanceof NetLaunchInfo ) {
nli = (NetLaunchInfo)params[1];
}
} }
means.add( InviteMeans.EMAIL ); means.add( InviteMeans.EMAIL );
means.add( InviteMeans.SMS_USER ); means.add( InviteMeans.SMS_USER );
@ -129,7 +133,9 @@ public class InviteChoicesAlert extends DlgDelegateAlert
String[] players = XwJNI.kplr_getPlayers(); String[] players = XwJNI.kplr_getPlayers();
inviteView.setChoices( means, lastSelMeans, players ) inviteView.setChoices( means, lastSelMeans, players )
.setCallbacks( this ); .setNli( nli )
.setCallbacks( this )
;
if ( false && BuildConfig.DEBUG ) { if ( false && BuildConfig.DEBUG ) {
OnClickListener ocl = new OnClickListener() { OnClickListener ocl = new OnClickListener() {

View file

@ -20,8 +20,11 @@
package org.eehouse.android.xw4; package org.eehouse.android.xw4;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.ImageView;
import android.widget.RadioButton; import android.widget.RadioButton;
import android.widget.RadioGroup; import android.widget.RadioGroup;
import android.widget.ScrollView; import android.widget.ScrollView;
@ -30,6 +33,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans; import org.eehouse.android.xw4.DlgDelegate.DlgClickNotify.InviteMeans;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType; import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
import org.eehouse.android.xw4.loc.LocUtils; import org.eehouse.android.xw4.loc.LocUtils;
@ -38,6 +46,7 @@ public class InviteView extends ScrollView
implements RadioGroup.OnCheckedChangeListener { implements RadioGroup.OnCheckedChangeListener {
private static final String TAG = InviteView.class.getSimpleName(); private static final String TAG = InviteView.class.getSimpleName();
private static final int QRCODE_SIZE = 512;
public interface ItemClicked { public interface ItemClicked {
public void meansClicked( InviteMeans means ); public void meansClicked( InviteMeans means );
@ -79,7 +88,9 @@ public class InviteView extends ScrollView
RadioButton button = (RadioButton)LocUtils RadioButton button = (RadioButton)LocUtils
.inflate( context, R.layout.invite_radio ); .inflate( context, R.layout.invite_radio );
button.setText( LocUtils.getString( context, means.getUserDescID() ) ); button.setText( LocUtils.getString( context, means.getUserDescID() ) );
mGroupHow.addView( button ); // -2: place before QR code and its explanatory text
int where = mGroupHow.getChildCount() - 2;
mGroupHow.addView( button, where );
mHowMeans.put( button, means ); mHowMeans.put( button, means );
} }
@ -100,6 +111,14 @@ public class InviteView extends ScrollView
return this; return this;
} }
public InviteView setNli( NetLaunchInfo nli )
{
if ( null != nli ) {
startQRCodeThread( nli );
}
return this;
}
public InviteView setCallbacks( ItemClicked procs ) { public InviteView setCallbacks( ItemClicked procs ) {
mProcs = procs; mProcs = procs;
return this; return this;
@ -117,7 +136,6 @@ public class InviteView extends ScrollView
result = mHowMeans.get(checked); result = mHowMeans.get(checked);
} }
} }
Log.d( TAG, "getChoice() => %s", result );
return result; return result;
} }
@ -163,4 +181,37 @@ public class InviteView extends ScrollView
findViewById( R.id.who_empty ) findViewById( R.id.who_empty )
.setVisibility( showEmpty ? View.VISIBLE : View.INVISIBLE ); .setVisibility( showEmpty ? View.VISIBLE : View.INVISIBLE );
} }
private void startQRCodeThread( NetLaunchInfo nli )
{
final String url = nli.makeLaunchUri( getContext() ).toString();
new Thread( new Runnable() {
@Override
public void run() {
try {
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
BitMatrix bitMatrix = multiFormatWriter.encode( url, BarcodeFormat.QR_CODE,
QRCODE_SIZE, QRCODE_SIZE );
final Bitmap bitmap = Bitmap.createBitmap( QRCODE_SIZE, QRCODE_SIZE,
Bitmap.Config.ARGB_8888 );
for ( int ii = 0; ii < QRCODE_SIZE; ++ii ) {
for ( int jj = 0; jj < QRCODE_SIZE; ++jj ) {
bitmap.setPixel( ii, jj, bitMatrix.get(ii, jj)
? Color.BLACK : Color.WHITE );
}
}
post( new Runnable() {
@Override
public void run() {
ImageView iv = (ImageView)findViewById( R.id.qr_view );
iv.setImageBitmap( bitmap );
}
} );
} catch ( WriterException we ) {
Log.ex( TAG, we );
}
}
} ).start();
}
} }

View file

@ -588,7 +588,7 @@ public class NetLaunchInfo implements Serializable {
String host = LocUtils.getString( context, R.string.invite_host ); String host = LocUtils.getString( context, R.string.invite_host );
host = NetUtils.forceHost( host ); host = NetUtils.forceHost( host );
Uri.Builder ub = new Uri.Builder() Uri.Builder ub = new Uri.Builder()
.scheme( "http" ) .scheme( "http" ) // PENDING: should be https soon
.path( String.format( "//%s%s", host, .path( String.format( "//%s%s", host,
LocUtils.getString(context, R.string.invite_prefix) ) ); LocUtils.getString(context, R.string.invite_prefix) ) );
appendInt( ub, LANG_KEY, lang ); appendInt( ub, LANG_KEY, lang );

View file

@ -52,7 +52,21 @@
<RadioGroup android:id="@+id/group_how" <RadioGroup android:id="@+id/group_how"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
/> >
<!-- RadioButtons will be inserted above this item. -->
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/qrcode_invite_summary"
android:textAppearance="?android:attr/textAppearanceMedium"
android:padding="5dp"
/>
<ImageView android:id="@+id/qr_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
</RadioGroup>
<TextView android:id="@+id/who_empty" <TextView android:id="@+id/who_empty"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -1039,6 +1039,9 @@
<string name="radio_who">Who?</string> <string name="radio_who">Who?</string>
<!-- Text shown only when there are not any previous opponents to invite --> <!-- Text shown only when there are not any previous opponents to invite -->
<string name="invite_who_empty_expl">empty expl</string> <string name="invite_who_empty_expl">empty expl</string>
<!-- Shown above QR code in the how-to-invite dialog -->
<string name="qrcode_invite_summary">Or just have your opponent scan this QRCode</string>
<!-- Radio button in invite choices dialog for list ways to send an invitation --> <!-- Radio button in invite choices dialog for list ways to send an invitation -->
<string name="radio_how">How?</string> <string name="radio_how">How?</string>
<!-- Button, on DEBUG builds only, causes invitee players to be robots --> <!-- Button, on DEBUG builds only, causes invitee players to be robots -->