Feat(ToolView): Add native api

Add native api to support clipboard operations
This commit is contained in:
2024-08-21 16:52:24 +08:00
parent 893131fe02
commit e0485ecc32
2 changed files with 67 additions and 0 deletions

View File

@@ -1,6 +1,8 @@
package top.fatweb.oxygen.toolbox.ui.view package top.fatweb.oxygen.toolbox.ui.view
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import android.webkit.ConsoleMessage
import androidx.compose.animation.core.Ease import androidx.compose.animation.core.Ease
import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.infiniteRepeatable
@@ -26,20 +28,25 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.kevinnzou.web.AccompanistWebChromeClient
import com.kevinnzou.web.WebView import com.kevinnzou.web.WebView
import com.kevinnzou.web.rememberWebViewStateWithHTMLData import com.kevinnzou.web.rememberWebViewStateWithHTMLData
import timber.log.Timber
import top.fatweb.oxygen.toolbox.R import top.fatweb.oxygen.toolbox.R
import top.fatweb.oxygen.toolbox.icon.Loading import top.fatweb.oxygen.toolbox.icon.Loading
import top.fatweb.oxygen.toolbox.icon.OxygenIcons import top.fatweb.oxygen.toolbox.icon.OxygenIcons
import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar import top.fatweb.oxygen.toolbox.ui.component.OxygenTopAppBar
import top.fatweb.oxygen.toolbox.util.NativeWebApi
@Composable @Composable
internal fun ToolViewRoute( internal fun ToolViewRoute(
@@ -67,6 +74,7 @@ internal fun ToolViewScreen(
isPreview: Boolean, isPreview: Boolean,
onBackClick: () -> Unit onBackClick: () -> Unit
) { ) {
val context = LocalContext.current
val infiniteTransition = rememberInfiniteTransition(label = "infiniteTransition") val infiniteTransition = rememberInfiniteTransition(label = "infiniteTransition")
@@ -150,8 +158,33 @@ internal fun ToolViewScreen(
.fillMaxSize() .fillMaxSize()
.imePadding(), .imePadding(),
state = webViewState, state = webViewState,
chromeClient = remember {
object : AccompanistWebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage?): Boolean {
consoleMessage?.let {
Timber.tag("WebView").log(
priority = when (it.messageLevel()) {
ConsoleMessage.MessageLevel.TIP -> Log.VERBOSE
ConsoleMessage.MessageLevel.LOG -> Log.INFO
ConsoleMessage.MessageLevel.WARNING -> Log.WARN
ConsoleMessage.MessageLevel.ERROR -> Log.ERROR
else -> Log.DEBUG
},
message = "${it.message()} (${it.lineNumber()})"
)
return true
}
return false
}
}
},
onCreated = { onCreated = {
it.settings.javaScriptEnabled = true it.settings.javaScriptEnabled = true
it.settings.domStorageEnabled = true
it.addJavascriptInterface(
NativeWebApi(context = context, webView = it),
"NativeApi"
)
} }
) )
} }

View File

@@ -0,0 +1,34 @@
package top.fatweb.oxygen.toolbox.util
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Context.CLIPBOARD_SERVICE
import android.webkit.JavascriptInterface
import android.webkit.WebView
class NativeWebApi(
private val context: Context,
private val webView: WebView
) {
@JavascriptInterface
fun copyToClipboard(text: String): Boolean {
val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager?
return clipboardManager?.let {
it.setPrimaryClip(ClipData.newPlainText("copy", text))
true
} ?: false
}
@JavascriptInterface
fun readClipboard(): String {
val clipboardManager = context.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager?
return clipboardManager?.primaryClip?.getItemAt(0)?.text?.toString() ?: ""
}
private fun callback(callback: String, vararg args: Any) {
val jsCode =
"$callback(${args.map { if (it is String) "'$it'" else it }.joinToString(", ")})"
webView.evaluateJavascript(jsCode, null)
}
}