getting there
This commit is contained in:
+1
@@ -68,6 +68,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
|
||||
_components = GlobalComponents.components
|
||||
|
||||
_engineView = createEngine(components)
|
||||
_components?.engineView = _engineView
|
||||
|
||||
val engineNativeView = engineView.asView()
|
||||
// Set layout parameters
|
||||
|
||||
+25
-6
@@ -17,6 +17,8 @@ import eu.lensai.flutter_mozilla_components.pigeons.ReaderableState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.SelectionAction
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
@@ -31,10 +33,12 @@ import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
||||
import mozilla.components.concept.base.crash.Breadcrumb
|
||||
import mozilla.components.concept.engine.DefaultSettings
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.concept.engine.EngineView
|
||||
import mozilla.components.concept.engine.mediaquery.PreferredColorScheme
|
||||
import mozilla.components.concept.fetch.Client
|
||||
import mozilla.components.feature.addons.AddonManager
|
||||
import mozilla.components.feature.addons.amo.AMOAddonsProvider
|
||||
import mozilla.components.feature.addons.logger
|
||||
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
|
||||
import mozilla.components.feature.addons.update.DefaultAddonUpdater
|
||||
import mozilla.components.feature.app.links.AppLinksInterceptor
|
||||
@@ -73,7 +77,7 @@ private const val DAY_IN_MINUTES = 24 * 60L
|
||||
@Suppress("LargeClass")
|
||||
open class DefaultComponents(
|
||||
private val applicationContext: Context,
|
||||
private val flutterEvents: GeckoStateEvents,
|
||||
val flutterEvents: GeckoStateEvents,
|
||||
val readerViewController: ReaderViewController,
|
||||
val selectionAction: SelectionAction,
|
||||
) {
|
||||
@@ -83,6 +87,8 @@ open class DefaultComponents(
|
||||
const val PREF_GLOBAL_PRIVACY_CONTROL = "sample_browser_global_privacy_control"
|
||||
}
|
||||
|
||||
var engineView: EngineView? = null
|
||||
|
||||
val preferences: SharedPreferences =
|
||||
applicationContext.getSharedPreferences(SAMPLE_BROWSER_PREFERENCES, Context.MODE_PRIVATE)
|
||||
|
||||
@@ -140,6 +146,7 @@ open class DefaultComponents(
|
||||
FileUploadsDirCleaner { applicationContext.cacheDir }
|
||||
}
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
val store by lazy {
|
||||
BrowserStore(
|
||||
middleware = listOf(
|
||||
@@ -156,6 +163,7 @@ open class DefaultComponents(
|
||||
).apply {
|
||||
this.flowScoped { flow ->
|
||||
flow.map { state -> state.selectedTabId }
|
||||
.distinctUntilChanged()
|
||||
.collect { tabId ->
|
||||
flutterEvents.onSelectedTabChange(
|
||||
tabId
|
||||
@@ -166,8 +174,10 @@ open class DefaultComponents(
|
||||
this.flowScoped { flow ->
|
||||
flow.mapNotNull { state -> state.tabs }
|
||||
.filterChanged {
|
||||
it.content.icon
|
||||
it.content
|
||||
}
|
||||
.ifAnyChanged { arrayOf (it.content.icon) }
|
||||
.debounce { 50 }
|
||||
.collect { tab ->
|
||||
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||
flutterEvents.onIconChange(
|
||||
@@ -182,6 +192,7 @@ open class DefaultComponents(
|
||||
.filterChanged {
|
||||
it.content.securityInfo
|
||||
}
|
||||
.debounce { 50 }
|
||||
.collect { tab ->
|
||||
flutterEvents.onSecurityInfoStateChange(
|
||||
tab.id,
|
||||
@@ -200,10 +211,11 @@ open class DefaultComponents(
|
||||
it.readerState
|
||||
}
|
||||
.ifAnyChanged { arrayOf(
|
||||
it.readerState.readerable,
|
||||
it.readerState.active,
|
||||
)
|
||||
it.readerState.readerable,
|
||||
it.readerState.active,
|
||||
)
|
||||
}
|
||||
.debounce { 50 }
|
||||
.collect { tab ->
|
||||
flutterEvents.onReaderableStateChange(
|
||||
tab.id,
|
||||
@@ -226,6 +238,7 @@ open class DefaultComponents(
|
||||
it.content.canGoForward,
|
||||
)
|
||||
}
|
||||
.debounce { 50 }
|
||||
.collect { tab ->
|
||||
flutterEvents.onHistoryStateChange(
|
||||
tab.id,
|
||||
@@ -261,8 +274,11 @@ open class DefaultComponents(
|
||||
it.content.private,
|
||||
it.content.fullScreen,
|
||||
it.content.progress,
|
||||
it.content.loading) }
|
||||
it.content.loading)
|
||||
}
|
||||
.debounce { 50 }
|
||||
.collect { tab ->
|
||||
logger.info("title: ${tab.content.title} ${tab.content.url}")
|
||||
flutterEvents.onTabContentStateChange(
|
||||
TabContentState(
|
||||
id = tab.id,
|
||||
@@ -283,6 +299,7 @@ open class DefaultComponents(
|
||||
.filterChanged {
|
||||
it.content.findResults
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.collect { tab ->
|
||||
tab.content.findResults
|
||||
flutterEvents.onFindResults(
|
||||
@@ -296,6 +313,8 @@ open class DefaultComponents(
|
||||
}
|
||||
}
|
||||
|
||||
icons.install(engine, this)
|
||||
|
||||
WebNotificationFeature(
|
||||
applicationContext,
|
||||
engine,
|
||||
|
||||
+10
-4
@@ -87,6 +87,7 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
||||
private var activity: Activity? = null
|
||||
|
||||
private lateinit var _flutterPluginBinding: FlutterPlugin.FlutterPluginBinding;
|
||||
private lateinit var _flutterEvents : GeckoStateEvents
|
||||
|
||||
init {
|
||||
Log.addSink(AndroidLogSink())
|
||||
@@ -95,14 +96,15 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
_flutterPluginBinding = flutterPluginBinding
|
||||
|
||||
val flutterEvents = GeckoStateEvents(_flutterPluginBinding.binaryMessenger)
|
||||
_flutterEvents = GeckoStateEvents(_flutterPluginBinding.binaryMessenger)
|
||||
|
||||
val readerViewController =
|
||||
ReaderViewController(_flutterPluginBinding.binaryMessenger)
|
||||
val selectionActionDelegate = SelectionAction(_flutterPluginBinding.binaryMessenger)
|
||||
|
||||
GlobalComponents.setUp(
|
||||
flutterPluginBinding.applicationContext,
|
||||
flutterEvents,
|
||||
_flutterEvents,
|
||||
readerViewController,
|
||||
selectionActionDelegate
|
||||
)
|
||||
@@ -141,7 +143,6 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
||||
fm.beginTransaction()
|
||||
.replace(FRAGMENT_CONTAINER_ID, nativeFragment)
|
||||
.commitAllowingStateLoss()
|
||||
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
@@ -152,7 +153,12 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
||||
this.activity = binding.activity
|
||||
|
||||
_flutterPluginBinding.platformViewRegistry.registerViewFactory(
|
||||
"eu.lensai/gecko", GeckoViewFactory(binding.activity, FRAGMENT_CONTAINER_ID))
|
||||
"eu.lensai/gecko", GeckoViewFactory(
|
||||
binding.activity,
|
||||
FRAGMENT_CONTAINER_ID,
|
||||
_flutterEvents
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
|
||||
+15
-4
@@ -5,20 +5,26 @@ import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||
import io.flutter.plugin.common.StandardMessageCodec
|
||||
import io.flutter.plugin.platform.PlatformView
|
||||
import io.flutter.plugin.platform.PlatformViewFactory
|
||||
|
||||
class GeckoViewFactory(private val activity: Activity, private val containerId: Int) : PlatformViewFactory(
|
||||
class GeckoViewFactory(
|
||||
private val activity: Activity,
|
||||
private val containerId: Int,
|
||||
private val flutterEvents: GeckoStateEvents
|
||||
) : PlatformViewFactory(
|
||||
StandardMessageCodec.INSTANCE) {
|
||||
override fun create(context: Context?, id: Int, args: Any?): PlatformView {
|
||||
return NativeFragmentView(this.activity, this.containerId)
|
||||
return NativeFragmentView(this.activity, this.containerId, this.flutterEvents)
|
||||
}
|
||||
}
|
||||
|
||||
private class NativeFragmentView(
|
||||
private val activity: Activity?,
|
||||
private val containerId: Int
|
||||
activity: Activity?,
|
||||
containerId: Int,
|
||||
private val flutterEvents: GeckoStateEvents
|
||||
) : PlatformView {
|
||||
private val container: View
|
||||
|
||||
@@ -32,6 +38,11 @@ private class NativeFragmentView(
|
||||
container.id = containerId
|
||||
}
|
||||
|
||||
override fun onFlutterViewAttached(flutterView: View) {
|
||||
super.onFlutterViewAttached(flutterView)
|
||||
flutterEvents.onFragmentReadyStateChange(true) { _ -> }
|
||||
}
|
||||
|
||||
override fun getView(): View {
|
||||
return container
|
||||
}
|
||||
|
||||
+35
@@ -2,17 +2,35 @@ package eu.lensai.flutter_mozilla_components.api
|
||||
|
||||
import android.util.Log
|
||||
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
||||
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoSessionApi
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.LoadUrlFlagsValue
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import mozilla.components.browser.state.action.ContentAction
|
||||
import mozilla.components.browser.state.selector.findTab
|
||||
import mozilla.components.browser.state.selector.selectedTab
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.TranslationOptions as PigeonTranslationOptions
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
||||
import mozilla.components.concept.base.images.ImageLoadRequest
|
||||
import mozilla.components.concept.engine.EngineSession
|
||||
import mozilla.components.concept.engine.EngineView
|
||||
import mozilla.components.concept.engine.translate.TranslationOptions
|
||||
import mozilla.components.feature.session.SessionUseCases
|
||||
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||
|
||||
class GeckoSessionApiImpl : GeckoSessionApi {
|
||||
private val sessionUseCases: SessionUseCases by lazy { GlobalComponents.components!!.sessionUseCases }
|
||||
private val store: BrowserStore by lazy { GlobalComponents.components!!.store }
|
||||
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
||||
private val thumbnailStorage: ThumbnailStorage by lazy { GlobalComponents.components!!.thumbnailStorage }
|
||||
private val events: GeckoStateEvents by lazy { GlobalComponents.components!!.flutterEvents }
|
||||
private val engineView: EngineView? by lazy { GlobalComponents.components!!.engineView }
|
||||
|
||||
override fun loadUrl(
|
||||
tabId: String?,
|
||||
@@ -124,4 +142,21 @@ class GeckoSessionApiImpl : GeckoSessionApi {
|
||||
lastAccess = lastAccess ?: System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
|
||||
override fun requestScreenshot(callback: (Result<ByteArray?>) -> Unit) {
|
||||
val tab = state.selectedTab
|
||||
if (tab != null) {
|
||||
engineView?.captureThumbnail { bitmap ->
|
||||
if (bitmap != null) {
|
||||
store.dispatch(ContentAction.UpdateThumbnailAction(tab.id, bitmap))
|
||||
val compressed = bitmap.toWebPBytes()
|
||||
callback(Result.success(compressed))
|
||||
} else {
|
||||
callback(Result.success(null))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(Exception("No selected tab for screenshot")))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+145
@@ -8,7 +8,18 @@ import eu.lensai.flutter_mozilla_components.pigeons.RestoreLocation as PigeonRes
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.RecoverableTab as PigeonRecoverableTab
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.SourceValue
|
||||
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
||||
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.FindResultState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.HistoryItem
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.HistoryState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.ReaderableState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.RestoreLocation
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
|
||||
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.browser.session.storage.RecoverableBrowserState
|
||||
import mozilla.components.browser.state.action.TabListAction
|
||||
import mozilla.components.browser.state.selector.findTab
|
||||
@@ -18,16 +29,21 @@ import mozilla.components.browser.state.state.ReaderState
|
||||
import mozilla.components.browser.state.state.SessionState
|
||||
import mozilla.components.browser.state.state.recover.RecoverableTab
|
||||
import mozilla.components.browser.state.state.recover.TabState
|
||||
import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
||||
import mozilla.components.concept.base.images.ImageLoadRequest
|
||||
import mozilla.components.concept.engine.Engine
|
||||
import mozilla.components.concept.engine.EngineSession
|
||||
import mozilla.components.concept.storage.HistoryMetadataKey
|
||||
import mozilla.components.feature.tabs.TabsUseCases
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||
|
||||
class GeckoTabsApiImpl() : GeckoTabsApi {
|
||||
private val tabsUseCases: TabsUseCases by lazy { GlobalComponents.components!!.tabsUseCases }
|
||||
private val engine: Engine by lazy { GlobalComponents.components!!.engine }
|
||||
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
||||
private val thumbnailStorage: ThumbnailStorage by lazy { GlobalComponents.components!!.thumbnailStorage }
|
||||
private val events: GeckoStateEvents by lazy { GlobalComponents.components!!.flutterEvents }
|
||||
|
||||
private fun restoreSource(source: SourceValue ) : SessionState.Source {
|
||||
return SessionState.Source.restore(
|
||||
@@ -88,6 +104,135 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
|
||||
}
|
||||
}
|
||||
|
||||
override fun syncEvents(
|
||||
onSelectedTabChange: Boolean,
|
||||
onTabListChange: Boolean,
|
||||
onTabContentStateChange: Boolean,
|
||||
onIconChange: Boolean,
|
||||
onSecurityInfoStateChange: Boolean,
|
||||
onReaderableStateChange: Boolean,
|
||||
onHistoryStateChange: Boolean,
|
||||
onFindResults: Boolean,
|
||||
onThumbnailChange: Boolean,
|
||||
) {
|
||||
if(onSelectedTabChange) {
|
||||
events.onSelectedTabChange(
|
||||
state.selectedTabId
|
||||
) { _ -> }
|
||||
}
|
||||
|
||||
if(onTabListChange) {
|
||||
events.onTabListChange(state.tabs.map {tab -> tab.id}) { _ -> }
|
||||
}
|
||||
|
||||
if(onTabContentStateChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
events.onTabContentStateChange(
|
||||
TabContentState(
|
||||
id = tab.id,
|
||||
contextId = tab.contextId,
|
||||
url = tab.content.url,
|
||||
title = tab.content.title,
|
||||
progress = tab.content.progress.toLong(),
|
||||
isPrivate = tab.content.private,
|
||||
isFullScreen = tab.content.fullScreen,
|
||||
isLoading = tab.content.loading
|
||||
)
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
if(onIconChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
if(tab.content.icon != null) {
|
||||
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||
events.onIconChange(
|
||||
tab.id,
|
||||
iconBytes
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(onSecurityInfoStateChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||
events.onSecurityInfoStateChange(
|
||||
tab.id,
|
||||
SecurityInfoState(
|
||||
tab.content.securityInfo.secure,
|
||||
tab.content.securityInfo.host,
|
||||
tab.content.securityInfo.issuer,
|
||||
)
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
if(onReaderableStateChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
events.onReaderableStateChange(
|
||||
tab.id,
|
||||
ReaderableState(
|
||||
tab.readerState.readerable,
|
||||
tab.readerState.active,
|
||||
)
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
if(onHistoryStateChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
events.onHistoryStateChange(
|
||||
tab.id,
|
||||
HistoryState(
|
||||
items = tab.content.history.items.map { item -> HistoryItem(
|
||||
url = item.uri,
|
||||
title = item.title
|
||||
) },
|
||||
currentIndex = tab.content.history.currentIndex.toLong(),
|
||||
canGoBack = tab.content.canGoBack,
|
||||
canGoForward = tab.content.canGoForward,
|
||||
)
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
if(onFindResults) {
|
||||
state.tabs.forEach { tab ->
|
||||
events.onFindResults(
|
||||
tab.id,
|
||||
tab.content.findResults.map { result -> FindResultState(
|
||||
activeMatchOrdinal = result.activeMatchOrdinal.toLong(),
|
||||
numberOfMatches = result.numberOfMatches.toLong(),
|
||||
isDoneCounting = result.isDoneCounting,
|
||||
) }
|
||||
) { _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
if(onThumbnailChange) {
|
||||
state.tabs.forEach { tab ->
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
val bitmap = thumbnailStorage.loadThumbnail(
|
||||
ImageLoadRequest(
|
||||
id = tab.id,
|
||||
//TODO: make this configurable
|
||||
size = 600,
|
||||
isPrivate = tab.content.private
|
||||
)
|
||||
).await()
|
||||
|
||||
if(bitmap != null) {
|
||||
val bytes = bitmap.toWebPBytes()
|
||||
runOnUiThread {
|
||||
events.onThumbnailChange(tab.id, bytes) { _ -> }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun selectTab(tabId: String) {
|
||||
tabsUseCases.selectTab(tabId = tabId)
|
||||
}
|
||||
|
||||
+4
-1
@@ -12,6 +12,7 @@ import mozilla.components.browser.state.action.ContentAction
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.lib.state.Middleware
|
||||
import mozilla.components.lib.state.MiddlewareContext
|
||||
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
|
||||
@@ -30,7 +31,9 @@ class FlutterEventMiddleware(private val flutterEvents: GeckoStateEvents) : Midd
|
||||
when (action) {
|
||||
is ContentAction.UpdateThumbnailAction -> {
|
||||
val bytes = action.thumbnail.toWebPBytes()
|
||||
flutterEvents.onThumbnailChange(action.sessionId, bytes) { _ -> }
|
||||
runOnUiThread {
|
||||
flutterEvents.onThumbnailChange(action.sessionId, bytes) { _ -> }
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// no-op
|
||||
|
||||
+64
-18
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
|
||||
// Autogenerated from Pigeon (v22.5.0), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||
|
||||
@@ -1239,6 +1239,7 @@ interface GeckoSessionApi {
|
||||
fun crashRecovery(tabIds: List<String>?)
|
||||
fun purgeHistory()
|
||||
fun updateLastAccess(tabId: String?, lastAccess: Long?)
|
||||
fun requestScreenshot(callback: (Result<ByteArray?>) -> Unit)
|
||||
|
||||
companion object {
|
||||
/** The codec used by GeckoSessionApi. */
|
||||
@@ -1550,11 +1551,30 @@ interface GeckoSessionApi {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoSessionApi.requestScreenshot$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { _, reply ->
|
||||
api.requestScreenshot{ result: Result<ByteArray?> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface GeckoTabsApi {
|
||||
fun syncEvents(onSelectedTabChange: Boolean, onTabListChange: Boolean, onTabContentStateChange: Boolean, onIconChange: Boolean, onSecurityInfoStateChange: Boolean, onReaderableStateChange: Boolean, onHistoryStateChange: Boolean, onFindResults: Boolean, onThumbnailChange: Boolean)
|
||||
fun selectTab(tabId: String)
|
||||
fun removeTab(tabId: String)
|
||||
fun addTab(url: String, selectTab: Boolean, startLoading: Boolean, parentId: String?, flags: LoadUrlFlagsValue, contextId: String?, source: SourceValue, private: Boolean, historyMetadata: HistoryMetadataKey?, additionalHeaders: Map<String, String>?): String
|
||||
@@ -1585,6 +1605,32 @@ interface GeckoTabsApi {
|
||||
@JvmOverloads
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: GeckoTabsApi?, messageChannelSuffix: String = "") {
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.syncEvents$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val onSelectedTabChangeArg = args[0] as Boolean
|
||||
val onTabListChangeArg = args[1] as Boolean
|
||||
val onTabContentStateChangeArg = args[2] as Boolean
|
||||
val onIconChangeArg = args[3] as Boolean
|
||||
val onSecurityInfoStateChangeArg = args[4] as Boolean
|
||||
val onReaderableStateChangeArg = args[5] as Boolean
|
||||
val onHistoryStateChangeArg = args[6] as Boolean
|
||||
val onFindResultsArg = args[7] as Boolean
|
||||
val onThumbnailChangeArg = args[8] as Boolean
|
||||
val wrapped: List<Any?> = try {
|
||||
api.syncEvents(onSelectedTabChangeArg, onTabListChangeArg, onTabContentStateChangeArg, onIconChangeArg, onSecurityInfoStateChangeArg, onReaderableStateChangeArg, onHistoryStateChangeArg, onFindResultsArg, onThumbnailChangeArg)
|
||||
listOf(null)
|
||||
} catch (exception: Throwable) {
|
||||
wrapError(exception)
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$separatedMessageChannelSuffix", codec)
|
||||
if (api != null) {
|
||||
@@ -2107,6 +2153,23 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
|
||||
GeckoPigeonCodec()
|
||||
}
|
||||
}
|
||||
fun onFragmentReadyStateChange(stateArg: Boolean, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange$separatedMessageChannelSuffix"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(stateArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
fun onTabListChange(tabIdsArg: List<String>, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
@@ -2337,23 +2400,6 @@ class ReaderViewController(private val binaryMessenger: BinaryMessenger, private
|
||||
}
|
||||
}
|
||||
}
|
||||
fun readerViewButtonVisibility(visibleArg: Boolean, callback: (Result<Unit>) -> Unit)
|
||||
{
|
||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility$separatedMessageChannelSuffix"
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||
channel.send(listOf(visibleArg)) {
|
||||
if (it is List<*>) {
|
||||
if (it.size > 1) {
|
||||
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||
} else {
|
||||
callback(Result.success(Unit))
|
||||
}
|
||||
} else {
|
||||
callback(Result.failure(createConnectionError(channelName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */
|
||||
class SelectionAction(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
// Typedefs for record types
|
||||
typedef HistoryEvent = ({String tabId, HistoryState history});
|
||||
@@ -12,74 +13,79 @@ typedef FindResultsEvent = ({String tabId, List<FindResultState> results});
|
||||
|
||||
class GeckoEventService extends GeckoStateEvents {
|
||||
// Stream controllers
|
||||
final _tabListController = StreamController<List<String>>.broadcast();
|
||||
final _selectedTabController = StreamController<String?>.broadcast();
|
||||
final _tabContentController = StreamController<TabContentState>.broadcast();
|
||||
final _historyController = StreamController<HistoryEvent>.broadcast();
|
||||
final _readerableController = StreamController<ReaderableEvent>.broadcast();
|
||||
final _securityInfoController =
|
||||
StreamController<SecurityInfoEvent>.broadcast();
|
||||
final _iconController = StreamController<IconEvent>.broadcast();
|
||||
final _thumbnailController = StreamController<ThumbnailEvent>.broadcast();
|
||||
final _findResultsController = StreamController<FindResultsEvent>.broadcast();
|
||||
final _fragmentStateSubject = BehaviorSubject.seeded(false);
|
||||
final _tabListSubject = BehaviorSubject<List<String>>();
|
||||
final _selectedTabSubject = BehaviorSubject<String?>();
|
||||
final _tabContentSubject = BehaviorSubject<TabContentState>();
|
||||
final _historySubject = BehaviorSubject<HistoryEvent>();
|
||||
final _readerableSubject = BehaviorSubject<ReaderableEvent>();
|
||||
final _securityInfoSubject = BehaviorSubject<SecurityInfoEvent>();
|
||||
final _iconSubject = BehaviorSubject<IconEvent>();
|
||||
final _thumbnailSubject = BehaviorSubject<ThumbnailEvent>();
|
||||
final _findResultsSubject = BehaviorSubject<FindResultsEvent>();
|
||||
|
||||
// Event streams
|
||||
Stream<List<String>> get tabListEvents => _tabListController.stream;
|
||||
Stream<String?> get selectedTabEvents => _selectedTabController.stream;
|
||||
Stream<TabContentState> get tabContentEvents => _tabContentController.stream;
|
||||
Stream<HistoryEvent> get historyEvents => _historyController.stream;
|
||||
Stream<ReaderableEvent> get readerableEvents => _readerableController.stream;
|
||||
Stream<bool> get fragmentReadyStateEvents => _fragmentStateSubject.stream;
|
||||
Stream<List<String>> get tabListEvents => _tabListSubject.stream;
|
||||
Stream<String?> get selectedTabEvents => _selectedTabSubject.stream;
|
||||
Stream<TabContentState> get tabContentEvents => _tabContentSubject.stream;
|
||||
Stream<HistoryEvent> get historyEvents => _historySubject.stream;
|
||||
Stream<ReaderableEvent> get readerableEvents => _readerableSubject.stream;
|
||||
Stream<SecurityInfoEvent> get securityInfoEvents =>
|
||||
_securityInfoController.stream;
|
||||
Stream<IconEvent> get iconEvents => _iconController.stream;
|
||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailController.stream;
|
||||
Stream<FindResultsEvent> get findResultsEvent =>
|
||||
_findResultsController.stream;
|
||||
_securityInfoSubject.stream;
|
||||
Stream<IconEvent> get iconEvents => _iconSubject.stream;
|
||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
||||
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
||||
|
||||
@override
|
||||
void onFragmentReadyStateChange(bool state) {
|
||||
_fragmentStateSubject.add(state);
|
||||
}
|
||||
|
||||
// Overridden methods
|
||||
@override
|
||||
void onTabListChange(List<String?> tabIds) {
|
||||
_tabListController.add(tabIds.nonNulls.toList());
|
||||
_tabListSubject.add(tabIds.nonNulls.toList());
|
||||
}
|
||||
|
||||
@override
|
||||
void onSelectedTabChange(String? id) {
|
||||
_selectedTabController.add(id);
|
||||
_selectedTabSubject.add(id);
|
||||
}
|
||||
|
||||
@override
|
||||
void onTabContentStateChange(TabContentState state) {
|
||||
_tabContentController.add(state);
|
||||
_tabContentSubject.add(state);
|
||||
}
|
||||
|
||||
@override
|
||||
void onHistoryStateChange(String id, HistoryState state) {
|
||||
_historyController.add((tabId: id, history: state));
|
||||
_historySubject.add((tabId: id, history: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onReaderableStateChange(String id, ReaderableState state) {
|
||||
_readerableController.add((tabId: id, readerable: state));
|
||||
_readerableSubject.add((tabId: id, readerable: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onSecurityInfoStateChange(String id, SecurityInfoState state) {
|
||||
_securityInfoController.add((tabId: id, securityInfo: state));
|
||||
_securityInfoSubject.add((tabId: id, securityInfo: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onIconChange(String id, Uint8List? bytes) {
|
||||
_iconController.add((tabId: id, bytes: bytes));
|
||||
_iconSubject.add((tabId: id, bytes: bytes));
|
||||
}
|
||||
|
||||
@override
|
||||
void onThumbnailChange(String id, Uint8List? bytes) {
|
||||
_thumbnailController.add((tabId: id, bytes: bytes));
|
||||
_thumbnailSubject.add((tabId: id, bytes: bytes));
|
||||
}
|
||||
|
||||
@override
|
||||
void onFindResults(String id, List<FindResultState?> results) {
|
||||
_findResultsController.add((tabId: id, results: results.nonNulls.toList()));
|
||||
_findResultsSubject.add((tabId: id, results: results.nonNulls.toList()));
|
||||
}
|
||||
|
||||
GeckoEventService.setUp({
|
||||
@@ -94,14 +100,14 @@ class GeckoEventService extends GeckoStateEvents {
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
unawaited(_tabListController.close());
|
||||
unawaited(_selectedTabController.close());
|
||||
unawaited(_tabContentController.close());
|
||||
unawaited(_historyController.close());
|
||||
unawaited(_readerableController.close());
|
||||
unawaited(_securityInfoController.close());
|
||||
unawaited(_iconController.close());
|
||||
unawaited(_thumbnailController.close());
|
||||
unawaited(_findResultsController.close());
|
||||
unawaited(_tabListSubject.close());
|
||||
unawaited(_selectedTabSubject.close());
|
||||
unawaited(_tabContentSubject.close());
|
||||
unawaited(_historySubject.close());
|
||||
unawaited(_readerableSubject.close());
|
||||
unawaited(_securityInfoSubject.close());
|
||||
unawaited(_iconSubject.close());
|
||||
unawaited(_thumbnailSubject.close());
|
||||
unawaited(_findResultsSubject.close());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
class GeckoReaderableService extends ReaderViewController {
|
||||
final ReaderViewEvents _events;
|
||||
|
||||
final _appearanceVisibility = StreamController<bool>.broadcast();
|
||||
final _readerVisibility = StreamController<bool>.broadcast();
|
||||
final _appearanceVisibility = BehaviorSubject<bool>();
|
||||
final _readerVisibility = BehaviorSubject<bool>();
|
||||
|
||||
Stream<bool> get appearanceVisibility => _appearanceVisibility.stream;
|
||||
Stream<bool> get readerVisibility => _readerVisibility.stream;
|
||||
|
||||
Future<void> toggleReaderView(bool enable) {
|
||||
return _events.onToggleReaderView(enable);
|
||||
@@ -25,11 +25,6 @@ class GeckoReaderableService extends ReaderViewController {
|
||||
_appearanceVisibility.add(visible);
|
||||
}
|
||||
|
||||
@override
|
||||
void readerViewButtonVisibility(bool visible) {
|
||||
_readerVisibility.add(visible);
|
||||
}
|
||||
|
||||
GeckoReaderableService.setUp({
|
||||
ReaderViewEvents? readerEvents,
|
||||
BinaryMessenger? binaryMessenger,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_mozilla_components/src/data/models/load_url_flags.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
|
||||
@@ -118,6 +120,14 @@ class GeckoSessionService {
|
||||
return _api.purgeHistory();
|
||||
}
|
||||
|
||||
Future<Uint8List?> requestScreenshot() {
|
||||
if (tabId != null) {
|
||||
throw Exception('Screenshot only allowed for selected (visible) tab.');
|
||||
}
|
||||
|
||||
return _api.requestScreenshot();
|
||||
}
|
||||
|
||||
Future<void> updateLastAccess({
|
||||
String? tabId, //If null = current tab
|
||||
DateTime? lastAccess, //If null datetime.now
|
||||
|
||||
@@ -10,6 +10,29 @@ class GeckoTabService {
|
||||
|
||||
GeckoTabService({GeckoTabsApi? api}) : _api = api ?? _apiInstance;
|
||||
|
||||
Future<void> syncEvents({
|
||||
bool onSelectedTabChange = true,
|
||||
bool onTabListChange = true,
|
||||
bool onTabContentStateChange = true,
|
||||
bool onIconChange = true,
|
||||
bool onSecurityInfoStateChange = true,
|
||||
bool onHistoryStateChange = true,
|
||||
bool onFindResults = true,
|
||||
bool onThumbnailChange = true,
|
||||
}) {
|
||||
return _api.syncEvents(
|
||||
onSelectedTabChange: onSelectedTabChange,
|
||||
onTabListChange: onTabListChange,
|
||||
onTabContentStateChange: onTabContentStateChange,
|
||||
onIconChange: onIconChange,
|
||||
onSecurityInfoStateChange: onSecurityInfoStateChange,
|
||||
onHistoryStateChange: onHistoryStateChange,
|
||||
onFindResults: onFindResults,
|
||||
onThumbnailChange: onThumbnailChange,
|
||||
onReaderableStateChange: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> selectTab({required String tabId}) {
|
||||
return _api.selectTab(tabId: tabId);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -7,7 +9,9 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/domain/services/gecko_browser.dart';
|
||||
|
||||
class GeckoView extends StatelessWidget {
|
||||
const GeckoView({super.key});
|
||||
final FutureOr<void> Function()? preInitializationStep;
|
||||
|
||||
const GeckoView({super.key, this.preInitializationStep});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -35,6 +39,7 @@ class GeckoView extends StatelessWidget {
|
||||
params.onPlatformViewCreated(value);
|
||||
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||
await preInitializationStep?.call();
|
||||
await GeckoBrowserService().showNativeFragment();
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
|
||||
// Autogenerated from Pigeon (v22.5.0), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||
|
||||
@@ -1589,6 +1589,28 @@ class GeckoSessionApi {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List?> requestScreenshot() async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoSessionApi.requestScreenshot$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_channel.send(null) as List<Object?>?;
|
||||
if (pigeonVar_replyList == null) {
|
||||
throw _createConnectionError(pigeonVar_channelName);
|
||||
} else if (pigeonVar_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: pigeonVar_replyList[0]! as String,
|
||||
message: pigeonVar_replyList[1] as String?,
|
||||
details: pigeonVar_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return (pigeonVar_replyList[0] as Uint8List?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeckoTabsApi {
|
||||
@@ -1604,6 +1626,28 @@ class GeckoTabsApi {
|
||||
|
||||
final String pigeonVar_messageChannelSuffix;
|
||||
|
||||
Future<void> syncEvents({required bool onSelectedTabChange, required bool onTabListChange, required bool onTabContentStateChange, required bool onIconChange, required bool onSecurityInfoStateChange, required bool onReaderableStateChange, required bool onHistoryStateChange, required bool onFindResults, required bool onThumbnailChange,}) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.syncEvents$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_channel.send(<Object?>[onSelectedTabChange, onTabListChange, onTabContentStateChange, onIconChange, onSecurityInfoStateChange, onReaderableStateChange, onHistoryStateChange, onFindResults, onThumbnailChange]) as List<Object?>?;
|
||||
if (pigeonVar_replyList == null) {
|
||||
throw _createConnectionError(pigeonVar_channelName);
|
||||
} else if (pigeonVar_replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: pigeonVar_replyList[0]! as String,
|
||||
message: pigeonVar_replyList[1] as String?,
|
||||
details: pigeonVar_replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> selectTab({required String tabId}) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
@@ -2199,6 +2243,8 @@ class GeckoCookieApi {
|
||||
abstract class GeckoStateEvents {
|
||||
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||
|
||||
void onFragmentReadyStateChange(bool state);
|
||||
|
||||
void onTabListChange(List<String> tabIds);
|
||||
|
||||
void onSelectedTabChange(String? id);
|
||||
@@ -2219,6 +2265,31 @@ abstract class GeckoStateEvents {
|
||||
|
||||
static void setUp(GeckoStateEvents? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange$messageChannelSuffix', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
pigeonVar_channel.setMessageHandler(null);
|
||||
} else {
|
||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final bool? arg_state = (args[0] as bool?);
|
||||
assert(arg_state != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange was null, expected non-null bool.');
|
||||
try {
|
||||
api.onFragmentReadyStateChange(arg_state!);
|
||||
return wrapResponse(empty: true);
|
||||
} on PlatformException catch (e) {
|
||||
return wrapResponse(error: e);
|
||||
} catch (e) {
|
||||
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabListChange$messageChannelSuffix', pigeonChannelCodec,
|
||||
@@ -2522,8 +2593,6 @@ abstract class ReaderViewController {
|
||||
|
||||
void appearanceButtonVisibility(bool visible);
|
||||
|
||||
void readerViewButtonVisibility(bool visible);
|
||||
|
||||
static void setUp(ReaderViewController? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||
{
|
||||
@@ -2551,31 +2620,6 @@ abstract class ReaderViewController {
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility$messageChannelSuffix', pigeonChannelCodec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
pigeonVar_channel.setMessageHandler(null);
|
||||
} else {
|
||||
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final bool? arg_visible = (args[0] as bool?);
|
||||
assert(arg_visible != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility was null, expected non-null bool.');
|
||||
try {
|
||||
api.readerViewButtonVisibility(arg_visible!);
|
||||
return wrapResponse(empty: true);
|
||||
} on PlatformException catch (e) {
|
||||
return wrapResponse(error: e);
|
||||
} catch (e) {
|
||||
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -624,10 +624,25 @@ abstract class GeckoSessionApi {
|
||||
required String? tabId, //If null = current tab
|
||||
required int? lastAccess, //If null datetime.now
|
||||
});
|
||||
|
||||
@async
|
||||
Uint8List? requestScreenshot();
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class GeckoTabsApi {
|
||||
void syncEvents({
|
||||
required bool onSelectedTabChange,
|
||||
required bool onTabListChange,
|
||||
required bool onTabContentStateChange,
|
||||
required bool onIconChange,
|
||||
required bool onSecurityInfoStateChange,
|
||||
required bool onReaderableStateChange,
|
||||
required bool onHistoryStateChange,
|
||||
required bool onFindResults,
|
||||
required bool onThumbnailChange,
|
||||
});
|
||||
|
||||
void selectTab({required String tabId});
|
||||
|
||||
void removeTab({required String tabId});
|
||||
@@ -767,6 +782,8 @@ abstract class GeckoCookieApi {
|
||||
|
||||
@FlutterApi()
|
||||
abstract class GeckoStateEvents {
|
||||
void onFragmentReadyStateChange(bool state);
|
||||
|
||||
void onTabListChange(List<String> tabIds);
|
||||
void onSelectedTabChange(String? id);
|
||||
|
||||
@@ -789,7 +806,6 @@ abstract class ReaderViewEvents {
|
||||
@FlutterApi()
|
||||
abstract class ReaderViewController {
|
||||
void appearanceButtonVisibility(bool visible);
|
||||
void readerViewButtonVisibility(bool visible);
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
|
||||
@@ -11,12 +11,13 @@ dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.1.8
|
||||
rxdart: ^0.28.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
lint: ^2.3.0
|
||||
pigeon: ^22.4.2
|
||||
pigeon: ^22.5.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
Reference in New Issue
Block a user