From a0975abcccc0c44529c2466bc39af7afe21a62f4 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Tue, 7 Jun 2022 10:35:46 -0500 Subject: [PATCH] Render result form fields Does not handle reported/item tables yet, or fillable forms. --- src/cheogram/res/layout/command_note.xml | 2 +- .../res/layout/command_result_field.xml | 32 ++++++ .../conversations/entities/Conversation.java | 99 +++++++++++++++++-- 3 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 src/cheogram/res/layout/command_result_field.xml diff --git a/src/cheogram/res/layout/command_note.xml b/src/cheogram/res/layout/command_note.xml index 79c4f35fd18002ba1ff868acbf9e55aae0a8dc8a..9754b468bb1fdc3b662fc7ad72d370af34cd7409 100644 --- a/src/cheogram/res/layout/command_note.xml +++ b/src/cheogram/res/layout/command_note.xml @@ -3,7 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> + + + + + + + + + diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index bf313e322aaad9148a222a5611432ffc95f895b9..5abb0d16fc0fe4aa1930ee9ae36aee476494d8b9 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -7,6 +7,7 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ArrayAdapter; import android.webkit.WebView; import android.webkit.WebViewClient; @@ -40,6 +41,7 @@ import eu.siacs.conversations.crypto.OmemoSetting; import eu.siacs.conversations.crypto.PgpDecryptionService; import eu.siacs.conversations.databinding.CommandPageBinding; import eu.siacs.conversations.databinding.CommandNoteBinding; +import eu.siacs.conversations.databinding.CommandResultFieldBinding; import eu.siacs.conversations.databinding.CommandWebviewBinding; import eu.siacs.conversations.persistance.DatabaseBackend; import eu.siacs.conversations.services.AvatarService; @@ -1300,14 +1302,14 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl this.binding = binding; } - abstract public void bind(Element el, int position); + abstract public void bind(Element el); } class ErrorViewHolder extends ViewHolder { public ErrorViewHolder(CommandNoteBinding binding) { super(binding); } @Override - public void bind(Element iq, int position) { + public void bind(Element iq) { binding.errorIcon.setVisibility(View.VISIBLE); Element error = iq.findChild("error"); @@ -1324,20 +1326,41 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public NoteViewHolder(CommandNoteBinding binding) { super(binding); } @Override - public void bind(Element note, int position) { + public void bind(Element note) { binding.message.setText(note.getContent()); - if (note.getAttribute("type").equals("error")) { + String type = note.getAttribute("type"); + if (type != null && type.equals("error")) { binding.errorIcon.setVisibility(View.VISIBLE); } } } + class ResultFieldViewHolder extends ViewHolder { + public ResultFieldViewHolder(CommandResultFieldBinding binding) { super(binding); } + + @Override + public void bind(Element field) { + String label = field.getAttribute("label"); + if (label == null) label = field.getAttribute("var"); + if (label == null) label = ""; + binding.label.setText(label); + + ArrayAdapter values = new ArrayAdapter(binding.getRoot().getContext(), R.layout.simple_list_item); + for (Element el : field.getChildren()) { + if (el.getName().equals("value") && el.getNamespace().equals("jabber:x:data")) { + values.add(el.getContent()); + } + } + binding.values.setAdapter(values); + } + } + class WebViewHolder extends ViewHolder { public WebViewHolder(CommandWebviewBinding binding) { super(binding); } @Override - public void bind(Element oob, int position) { + public void bind(Element oob) { binding.webview.getSettings().setJavaScriptEnabled(true); binding.webview.setWebViewClient(new WebViewClient() { @Override @@ -1354,6 +1377,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl final int TYPE_ERROR = 1; final int TYPE_NOTE = 2; final int TYPE_WEB = 3; + final int TYPE_RESULT_FIELD = 4; protected String mTitle; protected CommandPageBinding mBinding = null; @@ -1375,6 +1399,15 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl Element command = iq.findChild("command", "http://jabber.org/protocol/commands"); if (iq.getType() == IqPacket.TYPE.RESULT && command != null) { for (Element el : command.getChildren()) { + if (el.getName().equals("x") && el.getNamespace().equals("jabber:x:data")) { + String title = el.findChildContent("title", "jabber:x:data"); + if (title != null) { + mTitle = title; + ConversationPagerAdapter.this.notifyDataSetChanged(); + } + this.responseElement = el; + break; + } if (el.getName().equals("x") && el.getNamespace().equals("jabber:x:oob")) { String url = el.findChildContent("url", "jabber:x:oob"); if (url != null) { @@ -1398,16 +1431,60 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl @Override public int getItemCount() { if (response == null) return 0; + if (response.getType() == IqPacket.TYPE.RESULT && responseElement.getNamespace().equals("jabber:x:data")) { + int i = 0; + for (Element el : responseElement.getChildren()) { + if (!el.getNamespace().equals("jabber:x:data")) continue; + if (el.getName().equals("title")) continue; + if (el.getName().equals("field")) { + String type = el.getAttribute("type"); + if (type != null && type.equals("hidden")) continue; + } + + i++; + } + return i; + } return 1; } + public Element getItem(int position) { + if (response == null) return null; + + if (response.getType() == IqPacket.TYPE.RESULT) { + if (responseElement.getNamespace().equals("jabber:x:data")) { + int i = 0; + for (Element el : responseElement.getChildren()) { + if (!el.getNamespace().equals("jabber:x:data")) continue; + if (el.getName().equals("title")) continue; + if (el.getName().equals("field")) { + String type = el.getAttribute("type"); + if (type != null && type.equals("hidden")) continue; + } + + if (i < position) { + i++; + continue; + } + + return el; + } + } + } + + return responseElement == null ? response : responseElement; + } + @Override public int getItemViewType(int position) { if (response == null) return -1; if (response.getType() == IqPacket.TYPE.RESULT) { - if (responseElement.getName().equals("note")) return TYPE_NOTE; - if (responseElement.getNamespace().equals("jabber:x:oob")) return TYPE_WEB; + Element item = getItem(position); + if (item.getName().equals("note")) return TYPE_NOTE; + if (item.getNamespace().equals("jabber:x:oob")) return TYPE_WEB; + if (item.getName().equals("instructions") && item.getNamespace().equals("jabber:x:data")) return TYPE_NOTE; + if (item.getName().equals("field") && item.getNamespace().equals("jabber:x:data")) return TYPE_RESULT_FIELD; return -1; } else { return TYPE_ERROR; @@ -1429,14 +1506,18 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl CommandWebviewBinding binding = DataBindingUtil.inflate(LayoutInflater.from(container.getContext()), R.layout.command_webview, container, false); return new WebViewHolder(binding); } + case TYPE_RESULT_FIELD: { + CommandResultFieldBinding binding = DataBindingUtil.inflate(LayoutInflater.from(container.getContext()), R.layout.command_result_field, container, false); + return new ResultFieldViewHolder(binding); + } default: - return null; + throw new IllegalArgumentException("Unknown viewType: " + viewType); } } @Override public void onBindViewHolder(ViewHolder viewHolder, int position) { - viewHolder.bind(responseElement == null ? response : responseElement, position); + viewHolder.bind(getItem(position)); } public View getView() {