mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
fix imports
This commit is contained in:
parent
61ed6589bb
commit
a2056c7583
1 changed files with 292 additions and 293 deletions
|
|
@ -23,7 +23,6 @@ import androidx.compose.runtime.*
|
|||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.reader.OmnivoreWebView.Direction
|
||||
import com.google.gson.Gson
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -33,330 +32,330 @@ import java.util.*
|
|||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Composable
|
||||
fun WebReader(
|
||||
styledContent: String,
|
||||
webReaderViewModel: WebReaderViewModel,
|
||||
currentTheme: Themes?
|
||||
styledContent: String, webReaderViewModel: WebReaderViewModel, currentTheme: Themes?
|
||||
) {
|
||||
val javascriptActionLoopUUID: UUID by webReaderViewModel
|
||||
.javascriptActionLoopUUIDLiveData
|
||||
.observeAsState(UUID.randomUUID())
|
||||
val isDarkMode = isSystemInDarkTheme()
|
||||
|
||||
WebView.setWebContentsDebuggingEnabled(true)
|
||||
|
||||
// val showHighlightColorPalette = webReaderViewModel.showHighlightColorPalette.observeAsState()
|
||||
// val highlightColor = webReaderViewModel.highlightColor.observeAsState()
|
||||
|
||||
Box {
|
||||
AndroidView(factory = {
|
||||
OmnivoreWebView(it).apply {
|
||||
viewModel = webReaderViewModel
|
||||
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
val javascriptActionLoopUUID: UUID by webReaderViewModel.javascriptActionLoopUUIDLiveData.observeAsState(
|
||||
UUID.randomUUID()
|
||||
)
|
||||
val isDarkMode = isSystemInDarkTheme()
|
||||
|
||||
settings.javaScriptEnabled = true
|
||||
settings.allowContentAccess = true
|
||||
settings.allowFileAccess = true
|
||||
settings.domStorageEnabled = true
|
||||
WebView.setWebContentsDebuggingEnabled(true)
|
||||
|
||||
alpha = 1.0f
|
||||
viewModel?.showNavBar()
|
||||
currentTheme?.let { theme ->
|
||||
val bg = when (theme) {
|
||||
Themes.SYSTEM -> {
|
||||
if (isDarkMode) {
|
||||
Color.BLACK
|
||||
} else {
|
||||
Color.WHITE
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
theme.backgroundColor
|
||||
}
|
||||
}
|
||||
setBackgroundColor(bg.toInt())
|
||||
Box {
|
||||
AndroidView(factory = {
|
||||
OmnivoreWebView(it).apply {
|
||||
viewModel = webReaderViewModel
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val scrollbarColor = when (theme) {
|
||||
Themes.SYSTEM -> {
|
||||
if (isDarkMode) {
|
||||
Color.WHITE
|
||||
} else {
|
||||
Color.BLACK
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
|
||||
settings.javaScriptEnabled = true
|
||||
settings.allowContentAccess = true
|
||||
settings.allowFileAccess = true
|
||||
settings.domStorageEnabled = true
|
||||
|
||||
alpha = 1.0f
|
||||
viewModel?.showNavBar()
|
||||
currentTheme?.let { theme ->
|
||||
val bg = when (theme) {
|
||||
Themes.SYSTEM -> {
|
||||
if (isDarkMode) {
|
||||
Color.BLACK
|
||||
} else {
|
||||
Color.WHITE
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
theme.backgroundColor
|
||||
}
|
||||
}
|
||||
setBackgroundColor(bg.toInt())
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val scrollbarColor = when (theme) {
|
||||
Themes.SYSTEM -> {
|
||||
if (isDarkMode) {
|
||||
Color.WHITE
|
||||
} else {
|
||||
Color.BLACK
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
theme.scrollbarColor
|
||||
}
|
||||
}
|
||||
|
||||
val rad = 8f
|
||||
val shape = ShapeDrawable(
|
||||
RoundRectShape(
|
||||
floatArrayOf(
|
||||
rad, rad, rad, rad, rad, rad, rad, rad
|
||||
), null, null
|
||||
)
|
||||
)
|
||||
shape.paint.color = scrollbarColor.toInt()
|
||||
verticalScrollbarThumbDrawable = shape
|
||||
}
|
||||
}
|
||||
|
||||
webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(
|
||||
view: WebView?, request: WebResourceRequest?
|
||||
): Boolean {
|
||||
var handled: Boolean? = null
|
||||
request?.let {
|
||||
if (request.isForMainFrame && request.hasGesture() && viewModel != null) {
|
||||
viewModel?.showOpenLinkSheet(context, request.url)
|
||||
handled = true
|
||||
}
|
||||
}
|
||||
|
||||
return handled ?: super.shouldOverrideUrlLoading(view, request)
|
||||
}
|
||||
}
|
||||
|
||||
val javascriptInterface = AndroidWebKitMessenger { actionID, json ->
|
||||
webReaderViewModel.hasTappedExistingHighlight = false
|
||||
|
||||
when (actionID) {
|
||||
"userTap" -> {
|
||||
val tapCoordinates = Gson().fromJson(json, TapCoordinates::class.java)
|
||||
Log.d("wvt", "received tap action: $tapCoordinates")
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
webReaderViewModel.lastTapCoordinates = tapCoordinates
|
||||
actionMode?.finish()
|
||||
actionMode = null
|
||||
}
|
||||
}
|
||||
|
||||
"existingHighlightTap" -> {
|
||||
val tapCoordinates = Gson().fromJson(json, TapCoordinates::class.java)
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
webReaderViewModel.hasTappedExistingHighlight = true
|
||||
webReaderViewModel.lastTapCoordinates = tapCoordinates
|
||||
startActionMode(null, ActionMode.TYPE_FLOATING)
|
||||
}
|
||||
}
|
||||
|
||||
"writeToClipboard" -> {
|
||||
val quote = Gson().fromJson(json, HighlightQuote::class.java).quote
|
||||
quote.let { unwrappedQuote ->
|
||||
val clipboard =
|
||||
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(unwrappedQuote, unwrappedQuote)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
webReaderViewModel.handleIncomingWebMessage(actionID, json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addJavascriptInterface(javascriptInterface, "AndroidWebKitMessenger")
|
||||
|
||||
loadDataWithBaseURL(
|
||||
"file:///android_asset/",
|
||||
styledContent,
|
||||
"text/html; charset=utf-8",
|
||||
"utf-8",
|
||||
null
|
||||
)
|
||||
requestFocus()
|
||||
setOnKeyListener { _, keyCode, event ->
|
||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||
scrollVertically(OmnivoreWebView.Direction.UP)
|
||||
return@setOnKeyListener true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||
scrollVertically(OmnivoreWebView.Direction.DOWN)
|
||||
return@setOnKeyListener true
|
||||
}
|
||||
}
|
||||
}
|
||||
// default value
|
||||
false
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
theme.scrollbarColor
|
||||
}
|
||||
}
|
||||
|
||||
val rad = 8f
|
||||
val shape = ShapeDrawable(RoundRectShape(floatArrayOf(rad, rad, rad, rad, rad, rad, rad, rad), null, null))
|
||||
shape.paint.color = scrollbarColor.toInt()
|
||||
verticalScrollbarThumbDrawable = shape
|
||||
}
|
||||
}
|
||||
|
||||
webViewClient = object : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(
|
||||
view: WebView?,
|
||||
request: WebResourceRequest?
|
||||
): Boolean {
|
||||
var handled: Boolean? = null
|
||||
request?.let {
|
||||
if (request.isForMainFrame && request.hasGesture() && viewModel != null) {
|
||||
viewModel?.showOpenLinkSheet(context, request.url)
|
||||
handled = true
|
||||
}
|
||||
}, update = {
|
||||
if (javascriptActionLoopUUID != webReaderViewModel.lastJavascriptActionLoopUUID) {
|
||||
for (script in webReaderViewModel.javascriptDispatchQueue) {
|
||||
Log.d("js", "executing script: $script")
|
||||
it.evaluateJavascript(script, null)
|
||||
}
|
||||
webReaderViewModel.resetJavascriptDispatchQueue()
|
||||
}
|
||||
|
||||
return handled ?: super.shouldOverrideUrlLoading(view, request)
|
||||
}
|
||||
}
|
||||
|
||||
val javascriptInterface = AndroidWebKitMessenger { actionID, json ->
|
||||
webReaderViewModel.hasTappedExistingHighlight = false
|
||||
|
||||
when (actionID) {
|
||||
"userTap" -> {
|
||||
val tapCoordinates = Gson().fromJson(json, TapCoordinates::class.java)
|
||||
Log.d("wvt", "received tap action: $tapCoordinates")
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
webReaderViewModel.lastTapCoordinates = tapCoordinates
|
||||
actionMode?.finish()
|
||||
actionMode = null
|
||||
}
|
||||
}
|
||||
"existingHighlightTap" -> {
|
||||
val tapCoordinates = Gson().fromJson(json, TapCoordinates::class.java)
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
webReaderViewModel.hasTappedExistingHighlight = true
|
||||
webReaderViewModel.lastTapCoordinates = tapCoordinates
|
||||
startActionMode(null, ActionMode.TYPE_FLOATING)
|
||||
}
|
||||
}
|
||||
"writeToClipboard" -> {
|
||||
val quote = Gson().fromJson(json, HighlightQuote::class.java).quote
|
||||
quote.let { unwrappedQuote ->
|
||||
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
val clip = ClipData.newPlainText(unwrappedQuote, unwrappedQuote)
|
||||
clipboard.setPrimaryClip(clip)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
webReaderViewModel.handleIncomingWebMessage(actionID, json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addJavascriptInterface(javascriptInterface, "AndroidWebKitMessenger")
|
||||
|
||||
loadDataWithBaseURL(
|
||||
"file:///android_asset/",
|
||||
styledContent,
|
||||
"text/html; charset=utf-8",
|
||||
"utf-8",
|
||||
null
|
||||
)
|
||||
requestFocus()
|
||||
setOnKeyListener { _, keyCode, event ->
|
||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||
when (keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_UP -> {
|
||||
scrollVertically(Direction.UP)
|
||||
return@setOnKeyListener true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||
scrollVertically(Direction.DOWN)
|
||||
return@setOnKeyListener true
|
||||
}
|
||||
}
|
||||
}
|
||||
// default value
|
||||
false
|
||||
}
|
||||
}
|
||||
}, update = {
|
||||
if (javascriptActionLoopUUID != webReaderViewModel.lastJavascriptActionLoopUUID) {
|
||||
for (script in webReaderViewModel.javascriptDispatchQueue) {
|
||||
Log.d("js", "executing script: $script")
|
||||
it.evaluateJavascript(script, null)
|
||||
}
|
||||
webReaderViewModel.resetJavascriptDispatchQueue()
|
||||
}
|
||||
})
|
||||
// if (showHighlightColorPalette.value == true) {
|
||||
// HighlightColorPalette(
|
||||
// mode = if (isDarkMode) HighlightColorPaletteMode.Dark else HighlightColorPaletteMode.Light,
|
||||
// selectedColorName = highlightColor.value?.name ?: "yellow",
|
||||
// onColorSelected = {
|
||||
// webReaderViewModel.setHighlightColor(it)
|
||||
// },
|
||||
// modifier = Modifier
|
||||
// .align(Alignment.BottomCenter)
|
||||
// .padding(12.dp, 12.dp, 12.dp, 36.dp)
|
||||
// )
|
||||
// }
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class OmnivoreWebView(context: Context) : WebView(context), OnScrollChangeListener {
|
||||
var viewModel: WebReaderViewModel? = null
|
||||
var actionMode: ActionMode? = null
|
||||
val density = resources.displayMetrics.density
|
||||
var viewModel: WebReaderViewModel? = null
|
||||
var actionMode: ActionMode? = null
|
||||
val density = resources.displayMetrics.density
|
||||
|
||||
init {
|
||||
setOnScrollChangeListener(this)
|
||||
}
|
||||
|
||||
enum class Direction(val value: Int) {
|
||||
UP(-1),
|
||||
DOWN(1)
|
||||
}
|
||||
|
||||
fun scrollVertically(direction: Direction, heightFactor: Int = 10) {
|
||||
if (canScrollVertically(direction.value)) {
|
||||
val scrollByValue = height.div(heightFactor)
|
||||
scrollBy(0, direction.value.times(scrollByValue))
|
||||
}
|
||||
}
|
||||
|
||||
private val actionModeCallback = object : ActionMode.Callback2() {
|
||||
// Called when the action mode is created; startActionMode() was called
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
actionMode = mode
|
||||
if (viewModel?.hasTappedExistingHighlight == true) {
|
||||
Log.d("wv", "inflating existing highlight menu")
|
||||
mode.menuInflater.inflate(R.menu.highlight_selection_menu, menu)
|
||||
} else {
|
||||
viewModel?.showHighlightColorPalette()
|
||||
mode.menuInflater.inflate(R.menu.text_selection_menu, menu)
|
||||
}
|
||||
return true
|
||||
init {
|
||||
setOnScrollChangeListener(this)
|
||||
}
|
||||
|
||||
// Called each time the action mode is shown. Always called after onCreateActionMode, but
|
||||
// may be called multiple times if the mode is invalidated.
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
return false // Return false if nothing is done
|
||||
enum class Direction(val value: Int) {
|
||||
UP(-1), DOWN(1)
|
||||
}
|
||||
|
||||
// Called when the user selects a contextual menu item
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.annotateHighlight, R.id.annotate -> {
|
||||
val script = "var event = new Event('annotate');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
mode.finish()
|
||||
fun scrollVertically(direction: Direction, heightFactor: Int = 10) {
|
||||
if (canScrollVertically(direction.value)) {
|
||||
val scrollByValue = height.div(heightFactor)
|
||||
scrollBy(0, direction.value.times(scrollByValue))
|
||||
}
|
||||
}
|
||||
|
||||
private val actionModeCallback = object : ActionMode.Callback2() {
|
||||
// Called when the action mode is created; startActionMode() was called
|
||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
actionMode = mode
|
||||
if (viewModel?.hasTappedExistingHighlight == true) {
|
||||
Log.d("wv", "inflating existing highlight menu")
|
||||
mode.menuInflater.inflate(R.menu.highlight_selection_menu, menu)
|
||||
} else {
|
||||
viewModel?.showHighlightColorPalette()
|
||||
mode.menuInflater.inflate(R.menu.text_selection_menu, menu)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Called each time the action mode is shown. Always called after onCreateActionMode, but
|
||||
// may be called multiple times if the mode is invalidated.
|
||||
override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||
return false // Return false if nothing is done
|
||||
}
|
||||
|
||||
// Called when the user selects a contextual menu item
|
||||
override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
|
||||
return when (item.itemId) {
|
||||
R.id.annotateHighlight, R.id.annotate -> {
|
||||
val script = "var event = new Event('annotate');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.highlight -> {
|
||||
val script = "var event = new Event('highlight');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.copyHighlight -> {
|
||||
val script =
|
||||
"var event = new Event('copyHighlight');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.copyTextSelection -> {
|
||||
val script =
|
||||
"var event = new Event('copyTextSelection');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.removeHighlight -> {
|
||||
val script = "var event = new Event('remove');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
else -> {
|
||||
Log.d("Loggo", "${item.itemId} selected")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the user exits the action mode
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
Log.d("wv", "destroying menu: $mode")
|
||||
viewModel?.hasTappedExistingHighlight = false
|
||||
viewModel?.hideHighlightColorPalette()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.highlight -> {
|
||||
val script = "var event = new Event('highlight');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
|
||||
override fun onGetContentRect(mode: ActionMode?, view: View?, outRect: Rect?) {
|
||||
Log.d("wv", "outRect: $outRect, View: $view")
|
||||
if (viewModel?.lastTapCoordinates != null) {
|
||||
val xValue = (viewModel!!.lastTapCoordinates!!.tapX * density).toInt()
|
||||
val yValue = (viewModel!!.lastTapCoordinates!!.tapY * density).toInt()
|
||||
val rect = Rect(xValue, yValue, xValue, yValue)
|
||||
|
||||
Log.d(
|
||||
"wvt",
|
||||
"setting rect based on last tapped rect: ${viewModel?.lastTapCoordinates.toString()}"
|
||||
)
|
||||
Log.d("wvt", "rect: $rect")
|
||||
|
||||
outRect?.set(rect)
|
||||
} else {
|
||||
outRect?.set(left, top, right, bottom)
|
||||
}
|
||||
}
|
||||
R.id.copyHighlight -> {
|
||||
val script = "var event = new Event('copyHighlight');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.copyTextSelection -> {
|
||||
val script = "var event = new Event('copyTextSelection');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
R.id.removeHighlight -> {
|
||||
val script = "var event = new Event('remove');document.dispatchEvent(event);"
|
||||
evaluateJavascript(script) {
|
||||
clearFocus()
|
||||
mode.finish()
|
||||
actionMode = null
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
Log.d("Loggo", "${item.itemId} selected")
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the user exits the action mode
|
||||
override fun onDestroyActionMode(mode: ActionMode) {
|
||||
Log.d("wv", "destroying menu: $mode")
|
||||
viewModel?.hasTappedExistingHighlight = false
|
||||
viewModel?.hideHighlightColorPalette()
|
||||
actionMode = null
|
||||
override fun startActionMode(callback: ActionMode.Callback?): ActionMode {
|
||||
Log.d("wv", "startActionMode:callback called")
|
||||
return super.startActionMode(actionModeCallback)
|
||||
}
|
||||
|
||||
override fun onGetContentRect(mode: ActionMode?, view: View?, outRect: Rect?) {
|
||||
Log.d("wv", "outRect: $outRect, View: $view")
|
||||
if (viewModel?.lastTapCoordinates != null) {
|
||||
val xValue = (viewModel!!.lastTapCoordinates!!.tapX * density).toInt()
|
||||
val yValue = (viewModel!!.lastTapCoordinates!!.tapY * density).toInt()
|
||||
val rect = Rect(xValue, yValue, xValue, yValue)
|
||||
|
||||
Log.d("wvt", "setting rect based on last tapped rect: ${viewModel?.lastTapCoordinates.toString()}")
|
||||
Log.d("wvt", "rect: $rect")
|
||||
|
||||
outRect?.set(rect)
|
||||
} else {
|
||||
outRect?.set(left, top, right, bottom)
|
||||
}
|
||||
override fun startActionModeForChild(
|
||||
originalView: View?, callback: ActionMode.Callback?
|
||||
): ActionMode {
|
||||
Log.d("wv", "startActionMode:originalView:callback called")
|
||||
return super.startActionModeForChild(originalView, actionModeCallback)
|
||||
}
|
||||
}
|
||||
|
||||
override fun startActionMode(callback: ActionMode.Callback?): ActionMode {
|
||||
Log.d("wv", "startActionMode:callback called")
|
||||
return super.startActionMode(actionModeCallback)
|
||||
}
|
||||
override fun startActionMode(callback: ActionMode.Callback?, type: Int): ActionMode {
|
||||
Log.d("wv", "startActionMode:type called")
|
||||
return super.startActionMode(actionModeCallback, type)
|
||||
}
|
||||
|
||||
override fun startActionModeForChild(
|
||||
originalView: View?,
|
||||
callback: ActionMode.Callback?
|
||||
): ActionMode {
|
||||
Log.d("wv", "startActionMode:originalView:callback called")
|
||||
return super.startActionModeForChild(originalView, actionModeCallback)
|
||||
}
|
||||
|
||||
override fun startActionMode(callback: ActionMode.Callback?, type: Int): ActionMode {
|
||||
Log.d("wv", "startActionMode:type called")
|
||||
return super.startActionMode(actionModeCallback, type)
|
||||
}
|
||||
|
||||
override fun onScrollChange(view: View?, x: Int, y: Int, oldX: Int, oldY: Int) {
|
||||
viewModel?.onScrollChange((oldY - y).toFloat())
|
||||
}
|
||||
override fun onScrollChange(view: View?, x: Int, y: Int, oldX: Int, oldY: Int) {
|
||||
viewModel?.onScrollChange((oldY - y).toFloat())
|
||||
}
|
||||
}
|
||||
|
||||
class AndroidWebKitMessenger(val messageHandler: (String, String) -> Unit) {
|
||||
@JavascriptInterface
|
||||
fun handleIdentifiableMessage(actionID: String, jsonString: String) {
|
||||
messageHandler(actionID, jsonString)
|
||||
}
|
||||
@JavascriptInterface
|
||||
fun handleIdentifiableMessage(actionID: String, jsonString: String) {
|
||||
messageHandler(actionID, jsonString)
|
||||
}
|
||||
}
|
||||
|
||||
data class TapCoordinates(
|
||||
val tapX: Double,
|
||||
val tapY: Double
|
||||
val tapX: Double, val tapY: Double
|
||||
)
|
||||
|
||||
data class HighlightQuote(val quote: String?)
|
||||
|
|
|
|||
Loading…
Reference in a new issue