diff --git a/src/cheogram/java/com/cheogram/android/WebxdcPage.java b/src/cheogram/java/com/cheogram/android/WebxdcPage.java index 292420782ea092062cfb6bc2ff8c054cd1ac9fa8..88808523c83fd1bfbaa05c6ac286264ddf38ab98 100644 --- a/src/cheogram/java/com/cheogram/android/WebxdcPage.java +++ b/src/cheogram/java/com/cheogram/android/WebxdcPage.java @@ -421,5 +421,36 @@ public class WebxdcPage implements ConversationPage { builder.append("]"); return builder.toString(); } + + @JavascriptInterface + public String sendToChat(String message) { + try { + JSONObject jsonObject = new JSONObject(message); + + String text = null; + String data = null; + String name = null; + if (jsonObject.has("base64")) { + data = jsonObject.getString("base64"); + } + if (jsonObject.has("name")) { + name = jsonObject.getString("name"); + } + if (jsonObject.has("text")) { + text = jsonObject.getString("text"); + } + + Intent intent = new Intent(xmppConnectionService, ConversationsActivity.class); + intent.setAction(ConversationsActivity.ACTION_VIEW_CONVERSATION); + intent.putExtra(ConversationsActivity.EXTRA_CONVERSATION, ((Conversation) source.getConversation()).getUuid()); + if (text != null) intent.putExtra(Intent.EXTRA_TEXT, text); + if (data != null) intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("data:application/octet-stream;base64," + data)); + activity.get().startActivity(intent); + return null; + } catch (Exception e) { + e.printStackTrace(); + return e.toString(); + } + } } } diff --git a/src/cheogram/res/raw/webxdc.js b/src/cheogram/res/raw/webxdc.js index 9277a263378f38285d7136e6ec848e5c9992cfd7..31404e1ae71491ab7587cc579f77dbffefa98582 100644 --- a/src/cheogram/res/raw/webxdc.js +++ b/src/cheogram/res/raw/webxdc.js @@ -57,5 +57,61 @@ window.webxdc = (() => { element.click(); return promise; }, + + sendToChat: async (message) => { + const data = {}; + if (!message.file && !message.text) { + return Promise.reject("sendToChat() error: file or text missing"); + } + const blobToBase64 = (file) => { + const dataStart = ";base64,"; + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + let data = reader.result; + resolve(data.slice(data.indexOf(dataStart) + dataStart.length)); + }; + reader.onerror = () => reject(reader.error); + }); + }; + if (message.text) { + data.text = message.text; + } + + if (message.file) { + let base64content; + if (!message.file.name) { + return Promise.reject("sendToChat() error: file name missing"); + } + if ( + Object.keys(message.file).filter((key) => + ["blob", "base64", "plainText"].includes(key) + ).length > 1 + ) { + return Promise.reject("sendToChat() error: only one of blob, base64 or plainText allowed"); + } + + if (message.file.blob instanceof Blob) { + base64content = await blobToBase64(message.file.blob); + } else if (typeof message.file.base64 === "string") { + base64content = message.file.base64; + } else if (typeof message.file.plainText === "string") { + base64content = await blobToBase64( + new Blob([message.file.plainText]) + ); + } else { + return Promise.reject("sendToChat() error: none of blob, base64 or plainText set correctly"); + } + data.base64 = base64content; + data.name = message.file.name; + } + + const errorMsg = InternalJSApi.sendToChat(JSON.stringify(data)); + if (errorMsg) { + return Promise.reject(errorMsg); + } + }, + }; })();