feat(android): integrate web api & native AI chat button (#10239)
This commit is contained in:
@@ -1,26 +1,80 @@
|
||||
package app.affine.pro
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.content.res.ColorStateList
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateMargins
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import app.affine.pro.plugin.AIButtonPlugin
|
||||
import app.affine.pro.plugin.AffineThemePlugin
|
||||
import app.affine.pro.utils.dp
|
||||
import com.getcapacitor.BridgeActivity
|
||||
import com.getcapacitor.plugin.CapacitorCookies
|
||||
import com.getcapacitor.plugin.CapacitorHttp
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
class MainActivity : BridgeActivity() {
|
||||
class MainActivity : BridgeActivity(), AIButtonPlugin.Callback, AffineThemePlugin.Callback,
|
||||
View.OnClickListener {
|
||||
|
||||
init {
|
||||
registerPlugins(
|
||||
listOf(
|
||||
AffineThemePlugin::class.java,
|
||||
AIButtonPlugin::class.java,
|
||||
CapacitorHttp::class.java,
|
||||
CapacitorCookies::class.java,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.R)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
private val fab: FloatingActionButton by lazy {
|
||||
FloatingActionButton(this).apply {
|
||||
visibility = View.GONE
|
||||
layoutParams = CoordinatorLayout.LayoutParams(dp(52), dp(52)).apply {
|
||||
gravity = Gravity.END or Gravity.BOTTOM
|
||||
updateMargins(0, 0, dp(24), dp(86))
|
||||
}
|
||||
customSize = dp(52)
|
||||
setImageResource(R.drawable.ic_ai)
|
||||
setOnClickListener(this@MainActivity)
|
||||
val parent = bridge.webView.parent as CoordinatorLayout
|
||||
parent.addView(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun present() {
|
||||
lifecycleScope.launch {
|
||||
fab.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
lifecycleScope.launch {
|
||||
fab.hide()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onThemeChanged(darkMode: Boolean) {
|
||||
lifecycleScope.launch {
|
||||
fab.backgroundTintList = ColorStateList.valueOf(
|
||||
ContextCompat.getColor(
|
||||
this@MainActivity,
|
||||
if (darkMode) {
|
||||
R.color.layer_background_primary_dark
|
||||
} else {
|
||||
R.color.layer_background_primary
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
Toast.makeText(this, "TODO: Start AI chat~", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package app.affine.pro.plugin
|
||||
|
||||
import com.getcapacitor.Plugin
|
||||
import com.getcapacitor.PluginCall
|
||||
import com.getcapacitor.PluginMethod
|
||||
import com.getcapacitor.annotation.CapacitorPlugin
|
||||
|
||||
@CapacitorPlugin(name = "AIButton")
|
||||
class AIButtonPlugin : Plugin() {
|
||||
|
||||
interface Callback {
|
||||
fun present()
|
||||
fun dismiss()
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun present(call: PluginCall) {
|
||||
(activity as? Callback)?.present()
|
||||
call.resolve()
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun dismiss(call: PluginCall) {
|
||||
(activity as? Callback)?.dismiss()
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package app.affine.pro.plugin
|
||||
|
||||
import com.getcapacitor.Plugin
|
||||
import com.getcapacitor.PluginCall
|
||||
import com.getcapacitor.PluginMethod
|
||||
import com.getcapacitor.annotation.CapacitorPlugin
|
||||
|
||||
@CapacitorPlugin(name = "AffineTheme")
|
||||
class AffineThemePlugin : Plugin() {
|
||||
|
||||
interface Callback {
|
||||
fun onThemeChanged(darkMode: Boolean)
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
fun onThemeChanged(call: PluginCall) {
|
||||
(bridge.activity as? Callback)?.onThemeChanged(call.data.optBoolean("darkMode"))
|
||||
call.resolve()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package app.affine.pro.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.util.TypedValue
|
||||
|
||||
fun Context.dp(dp: Int) = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
dp.toFloat(),
|
||||
resources.displayMetrics
|
||||
).toInt()
|
||||
Reference in New Issue
Block a user