From 67cf702ada5367fff5f7c4c72ee5f499ca41f916 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Mon, 26 Sep 2022 12:49:10 -0700 Subject: [PATCH] update android js interface. send actionID and json to WebReaderViewModel --- .../omnivore/omnivore/ui/reader/WebReader.kt | 22 +++++------ .../omnivore/ui/reader/WebReaderViewModel.kt | 17 +++++++++ packages/appreader/src/index.jsx | 14 ++++--- packages/web/additional.d.ts | 7 ++-- .../components/templates/article/Article.tsx | 5 ++- .../templates/article/HighlightsLayer.tsx | 38 +++++++++---------- 6 files changed, 62 insertions(+), 41 deletions(-) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt index 074f42dce..98401f013 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt @@ -26,7 +26,7 @@ fun WebReaderLoadingContainer(slug: String, webReaderViewModel: WebReaderViewMod } if (webReaderParams != null) { - WebReader(webReaderParams!!) + WebReader(webReaderParams!!, webReaderViewModel) } else { // TODO: add a proper loading view Text("Loading...") @@ -35,7 +35,7 @@ fun WebReaderLoadingContainer(slug: String, webReaderViewModel: WebReaderViewMod @SuppressLint("SetJavaScriptEnabled") @Composable -fun WebReader(params: WebReaderParams) { +fun WebReader(params: WebReaderParams, webReaderViewModel: WebReaderViewModel) { WebView.setWebContentsDebuggingEnabled(true) val webReaderContent = WebReaderContent( @@ -66,7 +66,11 @@ fun WebReader(params: WebReaderParams) { webViewClient = object : WebViewClient() { } - addJavascriptInterface(AndroidWebKitMessageHandler(), "AndroidWebKitMessageHandler") + val javascriptInterface = AndroidWebKitMessenger { actionID, json -> + webReaderViewModel.handleIncomingWebMessage(actionID, json) + } + + addJavascriptInterface(javascriptInterface, "AndroidWebKitMessenger") loadDataWithBaseURL("file:///android_asset/", styledContent, "text/html; charset=utf-8", "utf-8", null); } @@ -139,15 +143,9 @@ class OmnivoreWebView(context: Context) : WebView(context) { } } - -class AndroidWebKitMessageHandler { +class AndroidWebKitMessenger(val messageHandler: (String, JSONObject) -> Unit) { @JavascriptInterface - fun handleMessage(jsonString: String) { - // TODO: safely parse actionID and data from message - // Maybe add a second function for calls that include actionID? - val message = JSONObject(jsonString) - Log.d("Loggo", "Handling message: $message") -// val actionID = message["actionID"] -// Log.d("Loggo", "Received message with ID: $actionID and jsonValue: $message") + fun handleIdentifiableMessage(actionID: String, jsonString: String) { + messageHandler(actionID, JSONObject(jsonString)) } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt index e0272e124..56ac308f7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt @@ -1,5 +1,6 @@ package app.omnivore.omnivore.ui.reader +import android.util.Log import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -15,6 +16,7 @@ import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import org.json.JSONObject import javax.inject.Inject data class WebReaderParams( @@ -111,6 +113,21 @@ class WebReaderViewModel @Inject constructor( } } + fun handleIncomingWebMessage(actionID: String, json: JSONObject) { + Log.d("Loggo", "receive action ID: $actionID, with json values: $json") + + // createHighlightMutation: (input) => +// mutation('createHighlight', input), +// deleteHighlightMutation: (highlightId) => +// mutation('deleteHighlight', { highlightId }), +// mergeHighlightMutation: (input) => +// mutation('mergeHighlight', input), +// updateHighlightMutation: (input) => +// mutation('updateHighlight', input), +// articleReadingProgressMutation: (input) => +// mutation('articleReadingProgress', input), + } + fun reset() { webReaderParamsLiveData.value = null } diff --git a/packages/appreader/src/index.jsx b/packages/appreader/src/index.jsx index 5ee77d405..34303abb5 100644 --- a/packages/appreader/src/index.jsx +++ b/packages/appreader/src/index.jsx @@ -7,18 +7,22 @@ import '@omnivore/web/styles/globals.css' import '@omnivore/web/styles/articleInnerStyling.css' const mutation = async (name, input) => { - const message = { actionID: name, ...input } - if (window.webkit) { // Send iOS a message const result = - await window?.webkit?.messageHandlers.articleAction?.postMessage(message) + await window?.webkit?.messageHandlers.articleAction?.postMessage({ + actionID: name, + ...input, + }) console.log('action result', result, result.result) return result.result } else { // Send android a message - console.log('sending android a message', message) - AndroidWebKitMessageHandler.handleMessage(JSON.stringify(message)) + console.log('sending android a message', name, input) + AndroidWebKitMessenger.handleIdentifiableMessage( + name, + JSON.stringify(input) + ) } } diff --git a/packages/web/additional.d.ts b/packages/web/additional.d.ts index 3519e849f..7f08f3cf6 100644 --- a/packages/web/additional.d.ts +++ b/packages/web/additional.d.ts @@ -1,7 +1,8 @@ export {} -declare type AndroidWebKitMessageHandler = { - handleMessage: (string) => void +declare type AndroidWebKitMessenger = { + // 1st argument is an actionID value, 2nd is jsonString + handleIdentifiableMessage: (string, string) => void } declare global { @@ -13,7 +14,7 @@ declare global { Intercom: Function intercomSettings: IntercomSettings analytics?: Analytics - AndroidWebKitMessageHandler?: AndroidWebKitMessageHandler + AndroidWebKitMessenger?: AndroidWebKitMessenger } } diff --git a/packages/web/components/templates/article/Article.tsx b/packages/web/components/templates/article/Article.tsx index 60cf13413..a8e535739 100644 --- a/packages/web/components/templates/article/Article.tsx +++ b/packages/web/components/templates/article/Article.tsx @@ -84,8 +84,9 @@ export function Article(props: ArticleProps): JSX.Element { window.webkit.messageHandlers.readingProgressUpdate?.postMessage({ progress: readingProgress, }) - } else if (typeof window?.AndroidWebKitMessageHandler != 'undefined') { - window.AndroidWebKitMessageHandler.handleMessage( + } else if (typeof window?.AndroidWebKitMessenger != 'undefined') { + window.AndroidWebKitMessenger.handleIdentifiableMessage( + 'readingProgressUpdate', JSON.stringify({ progress: readingProgress }) ) } diff --git a/packages/web/components/templates/article/HighlightsLayer.tsx b/packages/web/components/templates/article/HighlightsLayer.tsx index 44235fb13..80207fa9a 100644 --- a/packages/web/components/templates/article/HighlightsLayer.tsx +++ b/packages/web/components/templates/article/HighlightsLayer.tsx @@ -162,12 +162,10 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element { actionID: 'annotate', annotation: inputs.highlight?.annotation ?? '', }) - } else if (typeof window?.AndroidWebKitMessageHandler != 'undefined') { - window.AndroidWebKitMessageHandler.handleMessage( - JSON.stringify({ - actionID: 'annotate', - annotation: inputs.highlight?.annotation ?? '', - }) + } else if (typeof window?.AndroidWebKitMessenger != 'undefined') { + window.AndroidWebKitMessenger.handleIdentifiableMessage( + 'annotate', + JSON.stringify({ annotation: inputs.highlight?.annotation ?? '' }) ) } else { inputs.createHighlightForNote = async (note?: string) => { @@ -290,14 +288,17 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element { // highlight, so the app can display a native menu const rect = (target as Element).getBoundingClientRect() const message = { - actionID: 'showMenu', rectX: rect.x, rectY: rect.y, rectWidth: rect.width, rectHeight: rect.height, } - window?.webkit?.messageHandlers.viewerAction?.postMessage(message) - window?.AndroidWebKitMessageHandler?.handleMessage( + window?.webkit?.messageHandlers.viewerAction?.postMessage({ + actionID: 'showMenu', + ...message, + }) + window?.AndroidWebKitMessenger?.handleIdentifiableMessage( + 'existingHighlightTap', JSON.stringify(message) ) setFocusedHighlight(highlight) @@ -349,19 +350,18 @@ export function HighlightsLayer(props: HighlightsLayerProps): JSX.Element { } break case 'share': - const message = { - actionID: 'share', - highlightID: focusedHighlight?.id, - } - if (props.isAppleAppEmbed) { - window?.webkit?.messageHandlers.highlightAction?.postMessage( - message - ) + window?.webkit?.messageHandlers.highlightAction?.postMessage({ + actionID: 'share', + highlightID: focusedHighlight?.id, + }) } - window?.AndroidWebKitMessageHandler?.handleMessage( - JSON.stringify(message) + window?.AndroidWebKitMessenger?.handleIdentifiableMessage( + 'share', + JSON.stringify({ + highlightID: focusedHighlight?.id, + }) ) if (focusedHighlight) {