Use a RecyclerView for list of gateway options
If there are no gateways in the current account's roster, just show the
old "Jabber ID" label. Otherwise show a list of toggle buttons. These
buttons show the type of their gateway and change the JID input to
not autocomplete and to show a hint matching the jabber🆔gateway
prompt.
This is just UI, submit behaviour is unchanged. List is not yet populated by
this code.
This commit is contained in:
parent
d29b33863b
commit
49cbe7448e
|
@ -94,6 +94,8 @@ dependencies {
|
|||
implementation 'com.google.guava:guava:30.1.1-android'
|
||||
implementation 'io.michaelrocks:libphonenumber-android:8.12.36'
|
||||
implementation 'io.github.nishkarsh:android-permissions:2.1.6'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'org.solovyev.android.views:linear-layout-manager:0.5@aar'
|
||||
implementation urlFile('https://cloudflare-ipfs.com/ipfs/QmeqMiLxHi8AAjXobxr3QTfa1bSSLyAu86YviAqQnjxCjM/libwebrtc.aar', 'libwebrtc.aar')
|
||||
// INSERT
|
||||
}
|
||||
|
|
|
@ -168,15 +168,19 @@ public class ServiceDiscoveryResult {
|
|||
return this.features;
|
||||
}
|
||||
|
||||
public boolean hasIdentity(String category, String type) {
|
||||
public Identity getIdentity(String category, String type) {
|
||||
for (Identity id : this.getIdentities()) {
|
||||
if ((category == null || id.getCategory().equals(category)) &&
|
||||
(type == null || id.getType().equals(type))) {
|
||||
return true;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasIdentity(String category, String type) {
|
||||
return getIdentity(category, type) != null;
|
||||
}
|
||||
|
||||
public String getExtendedDiscoInformation(String formType, String name) {
|
||||
|
|
|
@ -2,31 +2,48 @@ package eu.siacs.conversations.ui;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.TextView;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.solovyev.android.views.llm.LinearLayoutManager;
|
||||
|
||||
import eu.siacs.conversations.Config;
|
||||
import eu.siacs.conversations.R;
|
||||
import eu.siacs.conversations.databinding.EnterJidDialogBinding;
|
||||
import eu.siacs.conversations.services.XmppConnectionService;
|
||||
import eu.siacs.conversations.entities.Account;
|
||||
import eu.siacs.conversations.entities.Contact;
|
||||
import eu.siacs.conversations.entities.Presence;
|
||||
import eu.siacs.conversations.entities.ServiceDiscoveryResult;
|
||||
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
|
||||
import eu.siacs.conversations.ui.interfaces.OnBackendConnected;
|
||||
import eu.siacs.conversations.ui.util.DelayedHintHelper;
|
||||
import eu.siacs.conversations.xmpp.Jid;
|
||||
import eu.siacs.conversations.xmpp.OnGatewayPromptResult;
|
||||
|
||||
public class EnterJidDialog extends DialogFragment implements OnBackendConnected, TextWatcher {
|
||||
|
||||
|
@ -51,6 +68,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
|||
private boolean sanityCheckJid = false;
|
||||
|
||||
private boolean issuedWarning = false;
|
||||
private GatewayListAdapter gatewayListAdapter = new GatewayListAdapter();
|
||||
|
||||
public static EnterJidDialog newInstance(
|
||||
final List<String> activatedAccounts,
|
||||
|
@ -129,6 +147,9 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
|||
binding.account.setAdapter(adapter);
|
||||
}
|
||||
|
||||
binding.gatewayList.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
|
||||
binding.gatewayList.setAdapter(gatewayListAdapter);
|
||||
|
||||
builder.setView(binding.getRoot());
|
||||
builder.setNegativeButton(R.string.cancel, null);
|
||||
builder.setPositiveButton(getArguments().getString(POSITIVE_BUTTON_KEY), null);
|
||||
|
@ -157,11 +178,7 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
|||
}
|
||||
try {
|
||||
if (Config.DOMAIN_LOCK != null) {
|
||||
accountJid =
|
||||
Jid.ofEscaped(
|
||||
(String) binding.account.getSelectedItem(),
|
||||
Config.DOMAIN_LOCK,
|
||||
null);
|
||||
accountJid = Jid.ofEscaped((String) binding.account.getSelectedItem(), Config.DOMAIN_LOCK, null);
|
||||
} else {
|
||||
accountJid = Jid.ofEscaped((String) binding.account.getSelectedItem());
|
||||
}
|
||||
|
@ -276,4 +293,156 @@ public class EnterJidDialog extends DialogFragment implements OnBackendConnected
|
|||
final String[] parts = domain.split("\\.");
|
||||
return parts.length >= 3 && SUSPICIOUS_DOMAINS.contains(parts[0]);
|
||||
}
|
||||
|
||||
protected class GatewayListAdapter extends RecyclerView.Adapter<GatewayListAdapter.ViewHolder> {
|
||||
protected class ViewHolder extends RecyclerView.ViewHolder {
|
||||
protected ToggleButton button;
|
||||
protected int index;
|
||||
|
||||
public ViewHolder(View view, int i) {
|
||||
super(view);
|
||||
this.button = (ToggleButton) view.findViewById(R.id.button);
|
||||
setIndex(i);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
button.setChecked(true); // Force visual not to flap to unchecked
|
||||
setSelected(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setIndex(int i) {
|
||||
this.index = i;
|
||||
button.setChecked(selected == i);
|
||||
}
|
||||
|
||||
public void useButton(int res) {
|
||||
button.setText(res);
|
||||
button.setTextOff(button.getText());
|
||||
button.setTextOn(button.getText());
|
||||
button.setChecked(selected == this.index);
|
||||
binding.gatewayList.setVisibility(View.VISIBLE);
|
||||
button.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void useButton(String txt) {
|
||||
button.setTextOff(txt);
|
||||
button.setTextOn(txt);
|
||||
button.setChecked(selected == this.index);
|
||||
binding.gatewayList.setVisibility(View.VISIBLE);
|
||||
button.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Pair<Contact,String>> gateways = new ArrayList();
|
||||
protected int selected = 0;
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
|
||||
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.enter_jid_dialog_gateway_list_item, null);
|
||||
return new ViewHolder(view, i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder viewHolder, int i) {
|
||||
viewHolder.setIndex(i);
|
||||
|
||||
if(i == 0) {
|
||||
if(getItemCount() < 2) {
|
||||
binding.gatewayList.setVisibility(View.GONE);
|
||||
} else {
|
||||
viewHolder.useButton(R.string.account_settings_jabber_id);
|
||||
}
|
||||
} else {
|
||||
viewHolder.useButton(getLabel(i));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return this.gateways.size() + 1;
|
||||
}
|
||||
|
||||
public void setSelected(int i) {
|
||||
int old = this.selected;
|
||||
this.selected = i;
|
||||
|
||||
if(i == 0) {
|
||||
binding.jid.setThreshold(1);
|
||||
binding.jid.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
|
||||
binding.jidLayout.setHint(R.string.account_settings_jabber_id);
|
||||
} else {
|
||||
binding.jid.setThreshold(999999); // do not autocomplete
|
||||
binding.jid.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
binding.jidLayout.setHint(this.gateways.get(i-1).second);
|
||||
binding.jid.setHint(null);
|
||||
binding.jid.setOnFocusChangeListener((v, hasFocus) -> {});
|
||||
}
|
||||
|
||||
notifyItemChanged(old);
|
||||
notifyItemChanged(i);
|
||||
}
|
||||
|
||||
public String getLabel(int i) {
|
||||
if (i == 0) return null;
|
||||
|
||||
for(Presence p : this.gateways.get(i-1).first.getPresences().getPresences()) {
|
||||
ServiceDiscoveryResult.Identity id;
|
||||
if(p.getServiceDiscoveryResult() != null && (id = p.getServiceDiscoveryResult().getIdentity("gateway", null)) != null) {
|
||||
return id.getType();
|
||||
}
|
||||
}
|
||||
|
||||
return gateways.get(i-1).first.getDisplayName();
|
||||
}
|
||||
|
||||
public String getSelectedLabel() {
|
||||
return getLabel(selected);
|
||||
}
|
||||
|
||||
public Pair<String, Pair<Jid,Presence>> getSelected() {
|
||||
if(this.selected == 0) {
|
||||
return null; // No gateway, just use direct JID entry
|
||||
}
|
||||
|
||||
Pair<Contact,String> gateway = this.gateways.get(this.selected - 1);
|
||||
|
||||
Pair<Jid,Presence> presence = null;
|
||||
for (Map.Entry<String,Presence> e : gateway.first.getPresences().getPresencesMap().entrySet()) {
|
||||
Presence p = e.getValue();
|
||||
if (p.getServiceDiscoveryResult() != null) {
|
||||
if (p.getServiceDiscoveryResult().getFeatures().contains("jabber:iq:gateway")) {
|
||||
if (e.getKey().equals("")) {
|
||||
presence = new Pair<>(gateway.first.getJid(), p);
|
||||
} else {
|
||||
presence = new Pair<>(gateway.first.getJid().withResource(e.getKey()), p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (p.getServiceDiscoveryResult().hasIdentity("gateway", null)) {
|
||||
if (e.getKey().equals("")) {
|
||||
presence = new Pair<>(gateway.first.getJid(), p);
|
||||
} else {
|
||||
presence = new Pair<>(gateway.first.getJid().withResource(e.getKey()), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return presence == null ? null : new Pair(gateway.second, presence);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.gateways.clear();
|
||||
notifyDataSetChanged();
|
||||
setSelected(0);
|
||||
}
|
||||
|
||||
public void add(Contact gateway, String prompt) {
|
||||
binding.gatewayList.setVisibility(View.VISIBLE);
|
||||
this.gateways.add(new Pair<>(gateway, prompt));
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gateway_list"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/jid_layout"
|
||||
android:layout_width="match_parent"
|
||||
|
|
14
src/main/res/layout/enter_jid_dialog_gateway_list_item.xml
Normal file
14
src/main/res/layout/enter_jid_dialog_gateway_list_item.xml
Normal file
|
@ -0,0 +1,14 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingRight="5dp">
|
||||
<ToggleButton
|
||||
android:id="@+id/button"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="?attr/edit_text_color"
|
||||
android:textSize="?attr/TextSizeBody1" />
|
||||
</LinearLayout>
|
Loading…
Reference in a new issue