From b955bc0ad75ee86d40c14d3a311d487cc552ad04 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Wed, 5 Oct 2022 11:06:54 -0500 Subject: [PATCH] Allow webview to intercept action before sending over XMPP This allows delaying to, eg, submit a form or otherwise. --- .../conversations/entities/Conversation.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/eu/siacs/conversations/entities/Conversation.java b/src/main/java/eu/siacs/conversations/entities/Conversation.java index 255b0e7ee9a38bdd703876fa86b16ee716506330..25e912bd701c781c96b7d7c842e313f6b6d23660 100644 --- a/src/main/java/eu/siacs/conversations/entities/Conversation.java +++ b/src/main/java/eu/siacs/conversations/entities/Conversation.java @@ -27,6 +27,7 @@ import android.widget.TextView; import android.widget.Toast; import android.widget.Spinner; import android.webkit.JavascriptInterface; +import android.webkit.WebMessage; import android.webkit.WebView; import android.webkit.WebViewClient; import android.webkit.WebChromeClient; @@ -1772,6 +1773,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl class WebViewHolder extends ViewHolder { public WebViewHolder(CommandWebviewBinding binding) { super(binding); } + protected String boundUrl = ""; @Override public void bind(Item oob) { @@ -1795,20 +1797,32 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl ConversationPagerAdapter.this.notifyDataSetChanged(); } }); - binding.webview.addJavascriptInterface(new JsObject(), "xmpp_xep0050"); - binding.webview.loadUrl(oob.el.findChildContent("url", "jabber:x:oob")); + final String url = oob.el.findChildContent("url", "jabber:x:oob"); + if (!boundUrl.equals(url)) { + binding.webview.addJavascriptInterface(new JsObject(), "xmpp_xep0050"); + binding.webview.loadUrl(url); + boundUrl = url; + } } class JsObject { @JavascriptInterface public void execute() { execute("execute"); } + + @JavascriptInterface public void execute(String action) { getView().post(() -> { + actionToWebview = null; if(CommandSession.this.execute(action)) { removeSession(CommandSession.this); } }); } + + @JavascriptInterface + public void preventDefault() { + actionToWebview = binding.webview; + } } } @@ -1966,6 +1980,7 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl protected XmppConnectionService xmppConnectionService; protected ArrayAdapter actionsAdapter; protected GridLayoutManager layoutManager; + protected WebView actionToWebview = null; CommandSession(String title, XmppConnectionService xmppConnectionService) { loading(); @@ -2264,12 +2279,18 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl public boolean execute(String action) { if (!action.equals("cancel") && !action.equals("prev") && !validate()) return false; + if (response == null) return true; Element command = response.findChild("command", "http://jabber.org/protocol/commands"); if (command == null) return true; String status = command.getAttribute("status"); if (status == null || (!status.equals("executing") && !action.equals("prev"))) return true; + if (actionToWebview != null) { + actionToWebview.postWebMessage(new WebMessage("xmpp_xep0050/" + action), Uri.parse("*")); + return false; + } + final IqPacket packet = new IqPacket(IqPacket.TYPE.SET); packet.setTo(response.getFrom()); final Element c = packet.addChild("command", Namespace.COMMANDS);