update android js interface. send actionID and json to WebReaderViewModel

This commit is contained in:
Satindar Dhillon
2022-09-26 12:49:10 -07:00
parent 4cfa99e063
commit 67cf702ada
6 changed files with 62 additions and 41 deletions

View File

@ -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))
}
}

View File

@ -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
}

View File

@ -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)
)
}
}

View File

@ -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
}
}

View File

@ -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 })
)
}

View File

@ -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) {